另一个小正则表达式问题

时间:2013-12-19 18:31:18

标签: php html regex

我知道不鼓励解析HTML,但我知道它是受控环境下的最佳选择。我的情况是,我需要一个正则表达式来在html页面上找到所有预格式化的文本(<pre>)语句。这似乎很容易谷歌,但我发现没有结果。另外,<pre>语句需要包含一个字符串,在我的例子中,“gisformat”。换句话说,这个正则表达式需要返回包含“gisformat”的HTML文件中的所有预格式化文本语句。我知道它是这样的,但我不确定放在中间的是什么:/<pre>(what should I put here)</pre>/

编辑1:我正在使用PHP,是的,我看过这篇文章,包括答案#2 RegEx match open tags except XHTML self-contained tags

3 个答案:

答案 0 :(得分:1)

正则表达方式:

preg_match_all('~<pre\b[^>]*>(?>[^<g]+|g(?!isformat)|<(?!/pre))*gisformat(?>[^<]+|<(?!/pre>))*</pre>~', $subject, $matches);
print_r($matches[0]);

DOM方式:

$doc = new DOMDocument();
@$doc->loadHTML($subject);
$preNodes = $doc->getElementsByTagName('pre');

foreach($preNodes as $preNode) {
    if (strpos($preNode->nodeValue, 'gisformat') !== false)
        $result[] = $preNode->ownerDocument->saveXML($preNode);
}
print_r($result);

模式细节:

 # the opening tag #
<pre\b [^>]* >

 # content before the first "gisformat" #
(?>
    [^<g]+         # all that is not a "<" or a "g"
  |               # OR
    g(?!isformat)  # a "g" not followed by "isformat"
  |               # OR
    <(?!/pre)      # a "<" not followed by "/pre" 
)*                # repeat the group zero or more times

 # target #
gisformat

 # content until the closing tag #
(?>[^<]+|<(?!/pre>))*

 # closing tag #
</pre>

答案 1 :(得分:0)

如果您已阅读以前的帖子并了解尝试在HTML上使用RegEx的缺点,我们可以提供应该完成工作的BASIC正则表达式。尝试使用

<pre>[^<]*?gisformat[^<]*?</pre>

如果在

区域内嵌套了其他标签,这将不起作用,但它是特定的,因为我可以很容易地看到你的样本。正如您在上面引用的文章RegEx match open tags except XHTML self-contained tags中所述,“它有时适合解析有限的,已知的HTML集”

如果你有HTML示例,请使用我的正则表达式作为启动器并使用http://regexpal.com/进行调整。

答案 2 :(得分:0)

如果标签是平衡的并且引擎与PCRE兼容,则会在某处找到gisformat

RegexFormat4 处理。

 # '~(?s)(?&PRE)(?(DEFINE)(?<PRE><pre>(?:(?&Core)gisformat(?&Core))</pre>)(?<Core>(?:(?>(?:(?!</?pre>|gisformat).)*)|(?&PRE)|(?&POST))*)(?<POST><pre>(?:(?:(?>(?:(?!</?pre>).)*)|(?&POST))*)</pre>))~'

 # -----------------------------------
 (?s)           # Dot-All modifier
 (?&PRE)        # Main function call
 # -----------------------------------

                # Subroutines

 (?(DEFINE)
      (?<PRE>
           <pre>
           (?:
                (?&Core) 
                gisformat
                (?&Core) 
           )
           </pre>
      )
      (?<Core>
           (?:
                (?>
                     (?:
                          (?! </?pre> | gisformat )
                          . 
                     )*
                )
             |  
                (?&PRE) 
             |  
                (?&POST) 
           )*
      )
      (?<POST>
           <pre>
           (?:
                (?:
                     (?>
                          (?:
                               (?! </?pre> )
                               . 
                          )*
                     )
                  |  
                     (?&POST) 
                )*
           )
           </pre>
      )
 )