preg_match 中的正则表达式不匹配行注释源代码并捕获错误的子模式
regex in preg_match to NOT match line comment source code and capture wrong subpattern
[注意:我重写了我的 post 以更好地描述我的问题,感谢马里奥,我'L'我之前回答过]
我想匹配这些模式(并且还允许中间有一些空格):
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#
但不匹配示例列表中的最后两行仍然匹配。我该如何修复我的正则表达式?是不是因为负面回顾必须在 紧接着 一些 固定长度字符串 之前检查东西?
您可以使用两种方法中的一种。
方法一:SKIP-FAIL regex
您可以匹配所有以 //
开头的行并跳过它们,并且只匹配您在其他上下文中的子字符串。
'~^(\s*//.*)(*SKIP)(*F)|^(?:\s*Connection\s+)?(.+?)\s*=\s*new\s+DBConnection~m'
$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
)
方法 2:可选的捕获组和一些 post-processing
在 PHP PCRE 正则表达式模式中,您不能使用无限宽度后视,这意味着内部模式无法用 *
、+
、*?
、+?
、?
、?
、{1,4}
、{3,}
量词。此外,您也不能使用嵌套交替。
通常的解决方法是使用可选捕获组并在找到匹配项后检查其值。如果组值不为空,则表示匹配应该"failed",丢弃,否则,抓住你需要的捕获。
这是一个正则表达式示例:
'~^(\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 demo:
$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
使用相同的技术。
[注意:我重写了我的 post 以更好地描述我的问题,感谢马里奥,我'L'我之前回答过]
我想匹配这些模式(并且还允许中间有一些空格):
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#
但不匹配示例列表中的最后两行仍然匹配。我该如何修复我的正则表达式?是不是因为负面回顾必须在 紧接着 一些 固定长度字符串 之前检查东西?
您可以使用两种方法中的一种。
方法一:SKIP-FAIL regex
您可以匹配所有以 //
开头的行并跳过它们,并且只匹配您在其他上下文中的子字符串。
'~^(\s*//.*)(*SKIP)(*F)|^(?:\s*Connection\s+)?(.+?)\s*=\s*new\s+DBConnection~m'
$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
)
方法 2:可选的捕获组和一些 post-processing
在 PHP PCRE 正则表达式模式中,您不能使用无限宽度后视,这意味着内部模式无法用 *
、+
、*?
、+?
、?
、?
、{1,4}
、{3,}
量词。此外,您也不能使用嵌套交替。
通常的解决方法是使用可选捕获组并在找到匹配项后检查其值。如果组值不为空,则表示匹配应该"failed",丢弃,否则,抓住你需要的捕获。
这是一个正则表达式示例:
'~^(\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 demo:
$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
使用相同的技术。