我正在阅读一个页面并尝试从中提取一些数据。我有兴趣使用bash,经过几个链接之后,我才知道“Shell参数扩展”可能会有所帮助,但我发现在我的脚本中使用它很困难。我知道使用 sed 可能会更容易,但据我所知,我想知道如何在 bash 中实现这一点。
shopt -s extglob
str='My work</u><br /><span style="color: rgb(34,34,34);"></span><span>abc-X7-27ABC | </span><span style="color: rgb(34,34,34);">build'
echo "${str//<.*>/|}"
我希望我的输出如下:My work|abc-X7-27ABC |build
我想过检查它是否只接受单词而不是模式,而且它似乎正在使用单词。
例如,
echo "${str//span style/|}"
可以工作但是
echo "${str//span.*style/|}"
没有
另一方面,我在其中一个链接中看到 接受模式。我很困惑,为什么它不能与我在上面使用的模式一起工作。
How to make sed do non-greedy match? (用户konsolebox的解决方案)
答案 0 :(得分:3)
你犯的一个错误是混合shell globbing和regex。在shell glob
中,点的字面意思是点字符,而不是任何字符的0或更多。
如果您尝试使用此代码:
echo "${str//<*>/|}"
然后会打印出来:
My work|build
答案 1 :(得分:1)
这不是一个答案,而是为了演示为什么不建议对这种HTML编辑使用模式匹配。我尝试了以下几点。
shopt -s extglob
set +H # Turn off history expansion, if necessary, to allow the !(...) pattern
echo ${str//+(<+(!(>))>)/|}
首先:即使对于像str='My work</u><br />bob<foo>build'
这样的简单字符串,它也不起作用。其次,对于原始问题中的字符串,它似乎锁定了shell;我怀疑这种复杂的模式会引发指数回溯。
以下是它的工作方式:
!(>)
是除>
+(!(>))
是一个或多个非>
字符。<+(!(>))>
是>
和<
>
字符
+(<+(!(>))>)
是一组或多组<...>
- 附上的非>
。我的理论是,由于!(>)
可以匹配多字符字符串以及单个字符,因此需要 ton 回溯。