Как сопоставить группы строк, которые не содержат подстроки - PullRequest
3 голосов
/ 06 марта 2012

Мне нужно сопоставить группы строк, которые имеют в качестве границ последовательность символов "__" (два подчеркивания)

, например:

hello __1the_re__ my name is __pe er33__

"1the_re" и "pe er33"должно совпадать

моя проблема в определении "строки, которая не содержит последовательность символов"

/__((?!__).*)__/

Я пробовал это, но это не работает ...

спасибо!

Ответы [ 3 ]

3 голосов
/ 06 марта 2012

Ты рядом:

/__((?!__).)*__/

работает.Звезда должна находиться за пределами повторяющейся группы, поэтому прогнозирование выполняется в каждой позиции, а не только сразу после ведущего __.

, так как это не захватывает правильный текст (я предполагаю, что вы хотитесодержимое между двойными подчеркиваниями, которые будут захвачены), вы, вероятно, хотите

/__((?:(?!__).)*)__/
1 голос
/ 06 марта 2012

Внутри вашей группировки вы хотите соответствовать одному из следующих:

  1. Любой символ, за которым следует любой символ, кроме _.
  2. Любой символ не _

Regex:

  /__(.[^_]|[^_])*__/

Когда первый матч первый, он продолжается. Для извлечения лучшего совпадения добавьте флаг отсутствия захвата и сопоставьте внутренний:

 /__((?:.[^_]|[^_])*)__/

Пример:

$subject = 'hello __1the_re__ my name is __pe er33__';
$pattern = '/__((?:.[^_]|[^_])*)__/';
$r = preg_match_all($pattern, $subject, $match);
print_r($match[1]);

Выход:

Array
(
    [0] => 1the_re
    [1] => pe er33
)

Но, очевидно, гораздо проще сделать квантификатор ленивым:

/__(.+?)__/
0 голосов
/ 06 марта 2012

Вы можете использовать не жадный знак: "?".

/__((?!__).*?)__/g
// javascript:
>>> "hello __1the_re__ my name is __pe er33__".match(/__((?!__).*?)__/g)
["__1the_re__", "__pe er33__"]
...