Not-group в регулярном выражении

Поэтому я понимаю, что [^A-Za-z] будет соответствовать любому символу, который не является буквой.

Есть ли способ сделать это с группой? Например: (?^:&) - будет соответствовать любой последовательности символов, которая не является последовательностью &

ПРИМЕЧАНИЕ: как Марк Рид указал, было бы бессмысленно сопоставлять пустую строку, так как пустая строка представляет собой последовательность символы, которые не являются последовательностью, поэтому я хотел бы, чтобы регулярное выражение соответствовало максимально возможному количеству символов

ДЛЯ ПРИМЕРА:

в Ben & Jerry's совпадения будут Ben и Jerry's (обратите внимание, что пробелы после Ben и до Jerry's также запечатлены.

ПРИМЕЧАНИЕ:, если это возможно, не используйте внешний вид, потому что я буду использовать регулярное выражение в JS script, а Javascript не поддерживает внешний вид.

Ответ 1

Что вам нужно, это регулярное выражение, которое будет соответствовать альтернативам и будет отображать только в первой группе, которая представит умеренный жадный токен (или развернутая версия для лучшей производительности - если у вас есть только 2 или 3):

&|((?:(?!&)[\s\S])+)

Смотрите демонстрацию regex (развернутая версия - &|([^&]*(?:&(?!amp;)[^&]*)*)

Образец:

  • & - соответствует & entity
  • | - или
  • ((?:(?!&)[\s\S])+) - сопоставляет и фиксирует в группу 1 любой фрагмент текста (1+ символов), который не является отправной точкой для последовательности &. Так как это для JS, вам нужен [\s\S] (или [^]) для соответствия любому символу, включая новую строку. В противном случае используйте . вместо этого (если вы только собираетесь сопоставлять строки).

var re = /&|((?:(?!&)[\s\S])+)/g; 
var str = 'abc Ben & Jerry\    foobar ssss  sss  sss &\n\n\nsssss&sssss     &\n\nsssss&sssss     &sssss\n&sssss&\n&&';
var res = [];
 
while ((m = re.exec(str)) !== null) {
    if (m.index === re.lastIndex) {// A part of code only necessary for the 
        re.lastIndex++;            // unrolled pattern (as it can match empty string)
    }
    res.push(m[1]);                // Only collect the captured texts
}
document.body.innerHTML = "<pre>BEFORE:<br/>" + str.replace(/&/g, '&amp;') + "</pre>";
document.body.innerHTML += "<pre>AFTER:<br/>" + res.join("") + "</pre>";

Ответ 2

Легко:

(.*?)(?:&amp;)|((?!&amp;).*)$

Демо

Объяснение:

  • (.*?): Возьмите все, кроме не жадных.
  • (?:&amp;): ?: - не захватывающая группа. Группа, которую вы не хотите получать.
  • ((?!&amp;).*)$: получить остальную часть строки, которая не является &amp;