我有一个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片段有什么好方法?
答案 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
}"