如何在perl中应用两个单独的正则表达式

时间:2013-12-05 01:02:53

标签: regex perl

我有一个shell片段,可以在数千个随机html页面中找到所有外部JavaScript脚本,这些页面使用<script src="…"范例包含所述脚本,并带有绝对URL:

find ./ -type f -print0 | xargs -0 \
    perl -nle 'print $1 \
        while (m%<script[^>]+((https?:)?//[-./0-9A-Z\_a-z]+)%ig);'

由于脚本也可以在JavaScript本身内动态加载,我想扩展我的代码段以匹配以.js结尾的绝对类似URL的字符串,最好出现在script标记内。 (这不是100%准确,但可能足以找到一些额外的外部脚本案例。)

我正在考虑像<script[^>]*>.*["']((((https?)?:)?//)?[-.0-9A-Za-z]+\.[A-Za-z]{2,}/[-./0-9A-Z\_a-z]+\.js)这样的东西,最后也可能会考虑.*</script>

确保在.js内多次提及script导致多个匹配(上面的正则表达式本身不会自行执行),以及我的两个表达式,这是一个棘手的部分。不匹配的方式是在输入中一次提到给定的$1匹配字符串时产生两个输出。

将这个新正则表达式添加到我的perl片段有什么好方法?

1 个答案:

答案 0 :(得分:0)

  

一个棘手的部分是确保多次提及.js   脚本导致多个匹配(上面的正则表达式赢得了   本身)...

这可以通过将预期的正则表达式分成两部分来实现 - 一部分用于<script>标记,另一部分用于.js匹配 - 并在嵌套循环中调用部分;通过修饰符c可以实现嵌套,这可以防止线条中的当前位置在匹配后重置,以及\G锚点匹配上一个g匹配停止的位置

  

......还有我表达的两种表达方式   从一次提到给定的$1匹配得到两个输出   输入中的字符串。

第一个表达式仅匹配<script …>标记,第二个表达式仅匹配<script></script>标记,确保了这一点。

因此,shell代码段的perl部分可能如下所示:

    perl -nle '
    print $1 while m%<script[^>]+((https?:)?//[-./0-9A-Z\_a-z]+)%ig;
    while (m%<script[^>]*>%ig)  # for each <script> tag
    {
     print $2 while m%          # allow multiple mentions of `.js`
     \G((?!</script>).)*?       # do not pass over </script>, be non-greedy
     ["'"'](((https?:)?//)?[-.0-9A-Za-z]+\.[A-Za-z]{2,}/[-./0-9A-Z\_a-z]+\.js)
                     %ixgc      # c: keep the Current position for outer loop
    }"