我编写了一个正则表达式模式,当我在Regexr中测试它时效果很好,但是当我在我的PHP代码中使用它时它并不总是匹配它应该匹配。
The regular expression,包括应该和不应匹配的一些示例。
应该匹配但不匹配的示例PHP代码:
preg_match('/^([~]{3,})\s*([\w-]+)?\s*(?:\{([\w-\s]+)\})?\s*(\2[\w-]+)?\s*$/', "~~~ {class} lang", $matches);
echo var_dump($matches);
我认为问题是由最后一个捕获组(\2[\w-]+)
中的反向引用引起的,但是,我无法知道如何解决这个问题。
答案 0 :(得分:2)
因为您指的是不存在的组(组2)。因此,请从正则表达式中删除\2
。
^([~]{3,})\s*([\w-]+)?\s*(?:\{([-\w\s]+)\})?\s*([\w-]+)?\s*$
~~~ {class} lang
| | | |
Group1| Group3 Group4
|
Missing group 2
答案 1 :(得分:2)
问题是由捕获组#2
引起的,您已将此组设为可选。因此,既然它可能存在,也可能不存在,你需要使你的反引用也是可选的,否则它总是寻找一个必需的组。
但是,由于所有组都是可选的,我只会递归第二组的子模式。
^(~{3,})\s*([\w-]+)?\s*(?:{([^}]+)})?\s*((?2))?\s*$
示例:
$str = '~~~ {class} lang';
preg_match('/^(~{3,})\s*([\w-]+)?\s*(?:{([^}]+)})?\s*((?2))?\s*$/', $str, $matches);
var_dump($matches);
输出
array(5) {
[0]=> string(16) "~~~ {class} lang"
[1]=> string(3) "~~~"
[2]=> string(0) "" # Returns "" for optional groups that dont exist
[3]=> string(5) "class"
[4]=> string(4) "lang"
}
答案 2 :(得分:0)
下面的答案帮助我弄清楚它为什么不起作用。然而,这两个答案都会给$str = '~~~ lang {class} lang';
带来正面匹配,这是我不想要的。
我修改了我的更改捕获组2到([\w-]*)
,这样即使在那个地方没有字符串,捕获组仍然存在但仍然是空的。这样所有以下字符串都匹配:
$str = '~~~ lang {no-lines float left} ';
$str = '~~~ {class} ';
$str = '~~~ lang';
$str = '~~~ {class } lang ';
$str = '~~~';
$str = '~~~lang{class}';
但是这个赢了:
$str = '~~~ css {class} php';
完整解决方案:
$str = '~~~ {class} lang';
preg_match('/^([~]{3,})\s*([\w-]*)?\s*(?:\{([\w-\s]+)\})?\s*(\2[\w-]+)?\s*$/', $str, $matches);
var_dump($matches);