正则表达式:检测<p> </p>之间存在的文本

时间:2012-01-21 04:34:35

标签: regex

我有一个插件标记[crayon ...],可能会也可能不会在<p></p>块中呈现,如下所示:

<p>This is a <b>sentence</b> [crayon ...] The Crayon [/crayon] of words. </p>

由于我的代码被<div>代码替换,<p></p>不相交,浏览器会为我关闭它,在我的插件上方留下一个空白段落。在任何情况下,标记都是无效的并且具有奇怪的结果。我的问题是我需要检测[crayon块之间是否有<p></p>。到目前为止,我找到了两种方法:

  1. 使用<p(?:\s+[^>]*)?>(.*?)</p(?:\s+[^>]*)?>并在捕获中搜索[crayon
  2. 对于<p[^>]*>(?:[^<]*<(?!/?p(\s+[^>]*)?>)[^>]+(\s+[^>]*)?>)*[^<]*\[crayon的情况使用<p>...[crayon,其中......不包含</p><p>以及类似的</p>方法[crayon]代码。
  3. 第二种方法难以阅读但如果在我的标记之前捕获</p>则会失败。它不需要任何进一步的处理就可以像{1}一样在<p></p>内找到我的标签。但是,第一个正则表达式更简单,执行速度更快。我应该使用哪种,有更好的方法吗?

    编辑:

    对于方法2,这种野兽有效:

    <p[^<]*>(?:[^<]*<(?!/?p(\s+[^>]*)?>)[^>]+(\s+[^>]*)?>)*[^<]*((?:\[crayon[^\]]*\].*?\[/crayon\])|(?:\[crayon[^\]]*/\]))(?:[^<]*<(?!/?p(\s+[^>]*)?>)[^>]+(\s+[^>]*)?>)*[^<]*</p[^<]*>

1 个答案:

答案 0 :(得分:1)

使用改进的正则表达式编辑,注意我也偷了你的开放p标记检测;)。在PHP上,必须为多行匹配添加s修饰符:

/(?<!<!--)<p[^<]*>(?:[^<]*<(?!/?p(\s+[^>]*)?>)[^>]+(\s+[^>]*)?>)*[^<]*\[crayon.*?\].*?\[\/crayon\].*?<\/p>(?!(\s)?-->)/s

以下字符串用于测试。预期5场比赛, 179 步骤(问题的单个正则表达式 285 步骤):

<p>This is a <b>sentence</b> [crayon]...[/crayon] of words.</p>
<p class="large"> Paragraph with parameters [crayon]...[/crayon]</p>
<p>[crayon with-parameters=true]...[/crayon]</p>
<p>
Multiline paragraph [crayon]...[/crayon].
Lorem ipsum.
</p>
<p>...</p><p>[crayon]...[/crayon]</p>
<!-- <p> --> This is a <b>sentence</b> [crayon]...[/crayon] of words.<!-- </p> -->
<pizza>yummy</pizza>

有什么改进吗?