PHP正则表达式匹配标签前瞻问题

时间:2016-04-21 17:05:19

标签: php regex google-analytics

我正在尝试检查网页是否存在Google Analytics分析脚本标记。这似乎应该很容易,但我的正则表达式技能似乎缺乏。因此,作为一个简单的示例,我尝试匹配具有" google-analytics"的开放和关闭脚本标记。他们之间。

例如,如果你有:

<junit fork="yes" forkmode="perTest" printsummary="off" threads="4">
    <classpath refid="test.classpath"/>
    <formatter type="brief" usefile="false"/>
    <batchtest todir="${test.results.dir}/xml">
        <formatter type="xml"/>
        <fileset dir="src" includes="**/*Test.java" />
    </batchtest>
</junit>

然后是正则表达式:

<script scr="whatever"></script>
<script>other script</script>
blah blah blah
<script>
   blah blah google-analytics
<script>

这将返回从第一个脚本标记开始的字符串,并包含其他脚本标记。如下所示:

/<script>([s/S/]*?google-analtics[s/S/]*?)<\/script>/

但当然我只想要字符串

other script</script> blah blah blah <script> blah blah google-analytics

所以下一步就是包括一个负向的前瞻:

blah blah google-analytics

但这似乎不起作用。我尝试了一堆不同的捕获组合和&#39; [s / S /] *?&#39;在前面和后面。

基本上我只是尝试匹配字符串,只要它不包含子字符串。这听起来像是一个普遍的问题,但对于我的生活,我无法开始工作。我有谷歌一点,所有的例子都很简单,但似乎没有工作。我一直在使用https://regex101.com/r/hN5dK5/2

进行测试

任何见解都会有所帮助。 (脚本以php身份运行)

2 个答案:

答案 0 :(得分:2)

正则表达式方法

首先,使用verbose模式以获得更好的可读性 考虑以下正则表达式:

<script>                 # match "<script>" literally
(?:(?!</script>)[\s\S])* # match anything except "</script>"
(?:google-analytics)     # look for "google-analytics" literally
(?:(?!</script>)[\s\S])* # same pattern as above
</script>                # closing "</script>" tag

your updated demo 中查看此方法的演示。

解析器方法

的SimpleXML

通常情况下,使用正则表达式分析HTML被认为是SO上的不良做法(请参阅this famous post),因此您不妨使用带解析器的方法和适当的{{1} }查询:

xpath

参见 demo on ideone.com

DOM文档

有人可能会争辩说,$xml = simplexml_load_string($html); $scripts = $xml->xpath("//script[contains(text(),'google-analytics')]"); print_r($scripts); 并非真正用于解析SimpleXML个文件(而不是顾名思义的HTML个文件),所以为了完整起见,XML的示例{1}}最后:

DOMDocument

答案 1 :(得分:0)

问题在于前瞻一直看到页面的末尾,所以它可能会起作用,但仅限于最后一个脚本标记。

我找到的解决方法是将通配符搜索限制为&#39;&lt;&#;之外的任何内容,例如:

/<script[^>]*>([^<]*?google-analytics.com[\s\S]*?)<\/script>/

部分:

[^<]*?

匹配任何不是&#39;&lt;&#39;的字符。这确保了&#39;脚本之间没有任何其他标签。标签和谷歌字符串。