Интересно, в чем проблема с backreference здесь:
preg_match_all('/__\((\'|")([^\1]+)\1/', "__('match this') . 'not this'", $matches);
он должен соответствовать строке между __ (''), но на самом деле он возвращает:
match this') . 'not this
есть идеи?
Сделайте свое регулярное выражение неровным:
preg_match_all('/__((\'|")([^\1]+)\1/U', "__('match this') . 'not this'", $matches)
Вы не можете использовать backreference внутри класса символов, потому что класс символов соответствует ровно одному символу, а обратная ссылка может потенциально соответствовать любому количеству символов или никому.
То, что вы пытаетесь сделать, требует негативного взгляда, а не отрицательного символьного класса:
preg_match_all('/__\(([\'"])(?:(?!\1).)+\1\)/', "__('match this') . 'not this'", $matches);
Я также изменил ваше чередование – \'|" – на класс символов – [\'"] – потому что он намного эффективнее, и я избежал внешних круглых скобок, чтобы они соответствовали буквальным круглым скобкам.
EDIT: Я думаю, мне нужно расширить это «более эффективное» замечание. Я привел пример, который Фридл использовал для демонстрации этого момента и протестировал его в RegexBuddy.
Применительно к целевому тексту abababdedfg ,
^[ag]+$ сообщает успех после трех шагов, тогда как
^(?:a|b|c|d|e|f|g)+$ принимает 55 шагов.
И это для успешного матча. Когда я пробую это на abababdedfz ,
^[ag]+$ сообщает о сбое после 21 шага;
^(?:a|b|c|d|e|f|g)+$ принимает 99 шагов.
В этом конкретном случае влияние на производительность настолько тривиально, что его даже не стоит упоминать. Я просто говорю, когда вы выбираете между классом персонажа и чередованием, которые совпадают с одинаковыми вещами, вы почти всегда должны идти с классом персонажа. Просто эмпирическое правило.
Я удивлен, что он не дал вам сообщение об ошибке в случае дисбаланса.
/ __ ( (\'|") ([^\1]+) \1 /
Этот [^\1] не будет принимать содержимое буфера захвата 1 и помещать его в символ
класс. Это то же самое, что и все символы, которые НЕ '1'.
Попробуй это:
/__\(('|").*?\1\).*/
Вы можете добавить внутреннюю скользящую скобку, чтобы просто зафиксировать, что между кавычками:
/__\(('|")(.*?)\1\).*/
Изменить: если внутренний интервал не разрешен, используйте регулярное выражение Qtax.
Поскольку, ('|").*?\1 хотя и не жадный, по-прежнему будет соответствовать всем __('all'this'will"match') . В этом случае __('all'this'will"match') и его лучше использовать ('[^']*'|"[^"]*) как
Вы можете использовать что-то вроде: /__\(("[^"]+"|'[^']+')\)/