[ПРИМЕЧАНИЕ: я переписываю свой пост, чтобы лучше описать мой вопрос, благодаря моей благодарности Марио, и я ответила ранее)
Я хочу, чтобы соответствовать этим шаблонам (а также позволяют несколько пробелов между):
Connection variable = new DBConnection
variable = new DBConnection
но НЕ совпадают:
//Connection variable = new DBConnection
//variable = new DBConnection
// Connection variable = new DBConnection
// variable = new DBConnection
и, наконец, захватить имя переменной.
Это мое регулярное выражение
#(?<!//)(?:\s*Connection\s+)+(.+?)\s*=\s*new\s+DBConnection#
но последние две строки в списке примеров несоответствий по-прежнему совпадают. Как я могу исправить свое регулярное выражение? Это потому, что негативные взгляды должны проверять вещи непосредственно перед немного строка фиксированной длины только?
Вы можете использовать один из двух подходов.
Вы можете сопоставить все строки, начинающиеся с //
и пропустить их, и только сопоставлять ваши подстроки в других контекстах.
'~^(\s*//.*)(*SKIP)(*F)|^(?:\s*Connection\s+)?(.+?)\s*=\s*new\s+DBConnection~m'
Увидеть regex demo
$re = '~^(\s*//.*)(*SKIP)(*F)|^(?:\s*Connection\s+)?(.+?)\s*=\s*new\s+DBConnection~m';
$str = "Connection variable = new DBConnection\n variable = new DBConnection\n //\n //Connection variable = new DBConnection\n //variable = new DBConnection\n // Connection variable = new DBConnection\n // variable = new DBConnection";
if (preg_match_all($re, $str, $matches)) {
print_r($matches[0]);
}
Выход:
Array
(
[0] => Connection variable = new DBConnection
[1] => variable = new DBConnection
)
В шаблонах регулярных выражений PHP PCRE нельзя использовать lookbehinds бесконечной ширины, что означает, что шаблоны внутри не могут быть количественно определены с помощью *
, +
, *?
, +?
, ?
, ?
, {1,4}
, {3,}
кванторы. Более того, вы также не можете использовать вложенное чередование.
Обычный обходной путь заключается в использовании дополнительная группа захвата и проверьте его значение после того, как совпадение найдено. Если значение группы не пустое, это означает, что совпадение должно быть «неудачным», отброшено, иначе захватите нужный вам захват.
Вот пример регулярного выражения:
'~^(\s*//)?(?:\s*Connection\s+)?(.+?)\s*=\s*new\s+DBConnection~m'
Увидеть regex demo:
Подстроки, выделенные зеленым цветом, соответствуют группе 1. Мы можем проверить их в коде так:
$result = ""; // Result is empty
if (preg_match($rx, $s, $m)) { // Is there a match?
if (empty($m[1])) { // Is the match group #1 empty?
$result = $m[0]; // If yes, we found a result
}
} // Else, result will stay empty
Увидеть PHP демо:
$strs = ['Connection variable = new DBConnection', 'variable = new DBConnection', '//Connection variable = new DBConnection', '//variable = new DBConnection'];
$rx = '~^(\s*//)?(?:\s*Connection\s+)?(.+?)\s*=\s*new\s+DBConnection~m';
foreach ($strs as $s) {
echo "$s:\n";
if (preg_match($rx, $s, $m)) {
if (empty($m[1])) {
echo "FOUND:" . $m[0] . "\n--------------\n";
}
} else {
echo "NOT FOUND\n--------------\n";
}
}
Выход:
Connection variable = new DBConnection:
FOUND:Connection variable = new DBConnection
--------------
variable = new DBConnection:
FOUND:variable = new DBConnection
--------------
//Connection variable = new DBConnection:
//variable = new DBConnection:
Та же техника может быть использована с preg_replace_callback
если вам нужно заменить.
Других решений пока нет …