我正在尝试检查网页是否存在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身份运行)
答案 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 中查看此方法的演示。
通常情况下,使用正则表达式分析HTML
被认为是SO
上的不良做法(请参阅this famous post),因此您不妨使用带解析器的方法和适当的{{1} }查询:
xpath
参见 demo on ideone.com 。
有人可能会争辩说,$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;脚本之间没有任何其他标签。标签和谷歌字符串。