PHP PCRE正则表达式


PHP PCRE regular expression

在LaTeX中,表达式'o{a}{b}表示运算符'o'接受两个参数a和b。LaTeX也接受'o{a},在这种情况下将第二个参数视为空字符串。

现在我尝试匹配正则表达式''''o'{(['s'S]*?)'}'{(['s'S]*?)'}对字符串'o{a}'o{a}{b}。当整个字符串不匹配时,它会错误地将其视为匹配。(这个字符串的正确解释是子字符串'o{a}{b}是唯一匹配的。)关键是我需要知道如何告诉PHP,如果有{后面的第一个}以外的东西,那么它不是一个匹配。

我该怎么做呢?

Edit:操作符的实参允许包含符号'{}。但是在这种情况下,整个字符串不匹配的原因是因为a}'o{a中的花括号不符合LaTeX规则(例如{必须在}之前),因此a}'o{a不能作为操作符的参数…

Edit2:另一方面,'o{{a}}{b}应该是匹配的,因为{a}是一个有效的参数

我建议这样做:

$s = '''o{a}''o{a}{b}';
echo "$s'n";  # Check string
preg_match('~'''o('{(?>[^{}''']++|(?1)|'''.)+'}){2}~', $s, $match);
print_r($match);

ideone演示

正则表达式:

  • 使用递归处理嵌套的大括号,
  • 也使用反斜杠([^{}''']'''.)来避免使用文本大括号作为语法大括号。

'''o             # Matches 'o
(                # Recursive group to be
  '{             # Matches {
  (?>            # Begin atomic group (just a group that makes the regex faster)
     [^{}''']++  # Any characteres except braces and backslash
  |
     (?1)        # Or recurse the outer group
  |
     '''.        # Or match an escaped character
  )+             # As many times as necessary
  '}             # Closing brace
){2}             # Repeat twice

当前正则表达式的问题是,一旦这部分匹配''''o'{(['s'S]*?),它将尝试寻找即将到来的下一个'},并且在那里,无论您是使用懒惰量词还是贪婪量词,都无关紧要。您需要在实际的'}出现在正则表达式之前以某种方式阻止它匹配}

这就是为什么你必须使用[^{}],因为你实际上可以在里面嵌套大括号,这是使用递归的理想情况。

要处理可能嵌套的大括号,您需要使用递归特性:

$pattern = <<<'EOD'
~
''o({(?>[^{}]+|(?-1))*}){2}
~x
EOD;
,其中(?-1)是对最后一个捕获组的子模式的引用。

我猜你需要考虑使用锚^$

$pattern = '/^''o'{.*'}('{.*'})?$/';

我不知道你认为ab的可接受值是多少,所以你可以在这里用合适的类替换.*

允许'0{a}'o{a}{b}格式。如果只匹配'o{a}{b},修改如下:

$pattern = '/^''o'{.*'}'{.*'}$/';

根据您上次的编辑,我建议将上述.*替换为[^{]*,如其他答案所述。