PHP Regex,忽略Alternating语句中的第一个分组

Chr*_*ris 0 php regex

我试图弄清楚如果使用preg_match不存在另一个语句,如何捕获一个语句.

示范文本:

<!-- InstanceBeginEditable name="doctitle" -->

<title>BU Libraries | Research Guides | Citing Your Sources</title>

<!-- InstanceEndEditable -->

<div id="standardpgt"><h1><!-- InstanceBeginEditable name="pagetitle" --><strong>Citing Your Sources</strong><!-- InstanceEndEditable --></h1></div>
Run Code Online (Sandbox Code Playgroud)

因为pagetitle存在,我想拉它而不是doctitle标签.当然,它们之间还有很多其他角色,但我想向你展示一个小样本.

如果pagetitle不存在,我想获取doctitle的内容.

扭曲的是我没有直接使用php代码,我通过配置文件传递正则表达式语句,然后脚本正在接受它并从语句中拉出第一组.

这就是我想出的:

((?!.*?<!--\s*?InstanceBeginEditable\s*?name=\x22pagetitle\x22\s*?-->.*?<!--\s*?InstanceEndEditable\s*?-->)<!--\s*?InstanceBeginEditable\s*?name=\x22doctitle\x22\s*?-->\s*?<title>(.*?)<\/title>\s*?<!--\s*?InstanceEndEditable\s*?-->|<!-- InstanceBeginEditable\s*?name=\x22pagetitle\x22\s*?-->(.*?)<!--\s*?InstanceEndEditable\s*?-->)
Run Code Online (Sandbox Code Playgroud)

问题是由于某种原因,如果它不起作用,php总是将第一个空组读取为组1.

例如,在上面的示例文本中,它将返回

0 -> <!-- InstanceBeginEditable name="pagetitle" --><strong>Citing Your Sources</strong><!-- InstanceEndEditable -->
1 -> 
2 -> <strong>Citing Your Sources</strong>
Run Code Online (Sandbox Code Playgroud)

我不能为生活弄清楚如何使这项工作.我也写了这个正则表达式:

(?(?=.*?<!--\s*?InstanceBeginEditable\s*?name=\x22pagetitle\x22\s*?-->.*?<!--\s*?InstanceEndEditable\s*?-->).*?<!-- InstanceBeginEditable\s*?name=\x22pagetitle\x22\s*?-->(.*?)<!--\s*?InstanceEndEditable\s*?-->|.*?<!--\s*?InstanceBeginEditable\s*?name=\x22doctitle\x22\s*?-->\s*?<title>(.*?)<\/title>\s*?<!--\s*?InstanceEndEditable\s*?-->)
Run Code Online (Sandbox Code Playgroud)

但这也不起作用.非常感谢你的帮助.

克里斯

jsa*_*ata 6

只需在整个表达式周围使用分支重置模式:(?| ...),如:

((?|(?!.*?<!--\s*?InstanceBeginEditable\s*?name=\x22pagetitle\x22\s*?-->.*?<!--\s*?InstanceEndEditable\s*?-->)<!--\s*?InstanceBeginEditable\s*?name=\x22doctitle\x22\s*?-->\s*?<title>(.*?)<\/title>\s*?<!--\s*?InstanceEndEditable\s*?-->|<!-- InstanceBeginEditable\s*?name=\x22pagetitle\x22\s*?-->(.*?)<!--\s*?InstanceEndEditable\s*?-->))s
Run Code Online (Sandbox Code Playgroud)

来自"man perlre":

"(?| pattern)"这是"分支重置"模式,它具有捕获缓冲区从每个交替分支中的相同起始点开始编号的特殊属性.它从perl 5.10.0开始提供.

捕获缓冲区从左到右编号,但在此构造内,为每个分支重新开始编号.

每个分支内的编号将正常,并且此构造后面的任何缓冲区都将编号,就好像构造只包含一个分支,即包含最多捕获缓冲区的分支.

当您想要捕获许多替代匹配中的一个时,此构造将非常有用.

考虑以下模式.下面的数字显示了将在哪个缓冲区中存储捕获的内容.

         # before  ---------------branch-reset----------- after
         / ( a )  (?| x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x
         # 1            2         2  3        2     3     4
Run Code Online (Sandbox Code Playgroud)