我正在尝试逐行读取文件以提取捕获组中的所有锚标记。
到目前为止,我有:
regex="(<a href=\")([A-Za-z0-9:/._-]+)\".*(<\/a>)"
while read line; do
if [[ $line =~ $regex ]]; then
#echo ${BASH_REMATCH}
href=${BASH_REMATCH[2]}
echo $href
fi
done < file.txt
虽然这几乎可以正常工作,因为我正在根据需要捕获网址,但我遇到的问题是当一行包含两个或多个锚<a>
标记时,此时我的正则表达式无效捕获第一个锚标记。
所以,我不知道,必须有一种方法来捕捉所有重复的群体。
示例文本将是:
This paragraph has only one anchor tag, <a href="http://google.com" target="_blank">google</a>, lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Some paragraph with a lot of anchor tags, <a href="http://en.wikipedia.org/wiki/Regular_expression" target="_blank">regular expression</a>, lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <a href="http://en.wikipedia.org/wiki/Bash_(Unix_shell)" target="_blank">Bash</a>. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <a href="http://stackoverflow.com/questions/ask" target="_blank">asking</a>, lorem ipsum dolor sit amet <a href="http://en.wikipedia.org" target="_blank">wikipedia</a>
您会发现在上面的文字file.txt
上运行我的bash脚本的结果是“:
http://google.com
http://en.wikipedia.org/wiki/Regular_expression
...如果您取消注释行#echo ${BASH_REMATCH}
,您将看到整个段落匹配,只捕获了第一个锚点。
如何继续捕获段落中的所有锚点模式?
谢谢你的时间!
答案 0 :(得分:2)
您可以使用while循环捕获所有匹配
regex="<a href=\"([A-Za-z0-9:/._-]+)\"[^<]*<\/a>(.*$)"
while read line; do
while [[ $line =~ $regex ]]; do
href=${BASH_REMATCH[1]}
line=${BASH_REMATCH[2]}
echo $href
done
done < file.txt
打印
http://google.com
http://en.wikipedia.org/wiki/Regular_expression
http://stackoverflow.com/questions/ask
http://en.wikipedia.org
答案 1 :(得分:1)
你试过grep -o
吗?那只打印比赛。
grep -Po '(?<=<a href=\")([A-Za-z0-9:/._-]+)(?=\".*?<\/a>)' file.txt
(?<=...)
积极回顾:匹配此模式前面的位置(?=...)
肯定前瞻:匹配此模式后面的位置.*?
非贪婪匹配:因此,您不会在第一个开放<a>
代码与最后一个结束</a>
代码使用前瞻并向后看你不能匹配周围的模式只需要他们的存在。这使grep -o
输出完全符合您的需要。
请注意:这种方法非常不稳定,评论等不明白。如果您需要此工具来处理重要事项,请使用xml / html解析器