> <img alt="Citizen Kane Poster" title="Citizen Kane Poster"
src="https://images-na.ssl-images-amazon.com/images/M/MV5BMTQ2Mjc1MDQwMl5BMl5BanBnXkFtZTcwNzUyOTUyMg@@._V1_UX182_CR0,0,182,268_AL_.jpg"
itemprop="image" />
我想从上面的文字中提取海报的网址。 这是我的grep声明:
count=$(grep -zPo '(?<=> <img alt=").*?src="\K.*?(?="itemprop="image")' ~/movie_local)
movie_local是我保存网站页面源的地方。 我正在学习grep而且还没有完全掌握它,所以请对我软一点。请你帮帮我吧? :)
答案 0 :(得分:2)
(如前所述,最好的解决方案是使用HTML解析器。)
使用 GNU grep
,请尝试使用此简化版本:
grep -zPo '<img alt=[^/]+?src="\K[^"]+' ~/movie_local
原始尝试的固定版本(请注意(?s)
前缀;请参阅下面的说明):
grep -zPo '(?s)> <img alt=".*?src="\K.*?(?=")' ~/movie_local
替代方案,[\s\S]
使用ad-hoc匹配任何字符,包括\n
:
grep -zPo '> <img alt="[\s\S]*?src="\K.*?(?=")' ~/movie_local
至于为什么你的尝试不起作用:
当您使用-P
(用于PCRE (Perl-Compatible Regular Expression支持)时, .
不匹配{ {1}}字符。 默认 ,因此,即使您使用\n
一次读取整个输入,-z
也不会跨行边界匹配。你有两个选择:
s
("dotall") - .*
- 这会使(?s)
匹配任何字符,包括{{ 1}} .
而不是\n
顺便说一句: [\s\S]
构造在语法上比较简单,有时更灵活替代到一个外观断言({{ 1}} 强>
.
进行更灵活的空白匹配 - 请注意\K
代替原始单个空格 - 您的后瞻断言将失败,因为lookbehind断言必须是固定长度(至少从GNU (?<=...)
v2.26开始)。(?<=>\s*<img alt=")
就可以了:\s*
grep
只删除与匹配的所有内容(不包括在输出中)。