sed:在模式中剪切字符串
我有许多XHTML文件,其内容如下:sed:在模式中剪切字符串,sed,Sed,我有许多XHTML文件,其内容如下: <h:panelGroup rendered="#{not accessBean.isUserLoggedIn}"> <h:form> <p:panel style="margin-top:10px"> <table style="margin:10px"> <tbody> <
<h:panelGroup rendered="#{not accessBean.isUserLoggedIn}">
<h:form>
<p:panel style="margin-top:10px">
<table style="margin:10px">
<tbody>
<tr>
<td align="center">#{i.m['Login']}</td>
<td align="center">
<h:inputText value="#{accessBean.login}" />
</td>
</tr>
<tr>
<td align="center">#{i.m['Password']}</td>
<td align="center">
<h:inputSecret value="#{accessBean.password}" />
</td>
</tr>
</tbody>
</table>
<p:commandButton ajax="false" value="#{i.m['Submit']}" action="#{accessBean.login}" />
</p:panel>
</h:form>
</h:panelGroup>
在我可以执行的目录中递归地运行它
find . -iname '*.xhtml' -type f -exec sed -i -e "s/#{i.m\['\(.*\)']}/\1/g" {} \;
在这里,任何字符串
可以是任何人类可读的HTML可显示字符,即字母表、数字、其他字符等。这就是为什么我使用regex(*)
但它似乎工作得并不完美
下面是我使用echo进行的一些测试:
$echo“{i.m['Login']}”sed-e“s/{i.m\['(.*\')]}/\1/g”
结果:
<td align="center">Login</td>
<p:commandButton ajax="false" value="Submit" action="#{accessBean.login}" />
<p:commandButton ajax="false" value="Submit']}" action="#{accessBean.login}" /> <td align="center">#{i.m['Login</td>
登录
嗯$echo”“| sed-e”s/#{i.m\['(.*\')]}/\1/g”
结果:
<td align="center">Login</td>
<p:commandButton ajax="false" value="Submit" action="#{accessBean.login}" />
<p:commandButton ajax="false" value="Submit']}" action="#{accessBean.login}" /> <td align="center">#{i.m['Login</td>
嗯$echo“{i.m['Login']}”sed-e“s/{i.m\['(.*\')]}/\1/g”
结果:
<td align="center">Login</td>
<p:commandButton ajax="false" value="Submit" action="#{accessBean.login}" />
<p:commandButton ajax="false" value="Submit']}" action="#{accessBean.login}" /> <td align="center">#{i.m['Login</td>
{i.m['Login
诺克我使用的是Ubuntu 18.04。这里的问题是你没有考虑到regexp的贪婪本质。你需要防止你的regexp占用额外的
“
s:
sed-e“s/#{i.m['([^']*)']}/\1/g”
这也是David C.Rankin的解决方案起作用的原因。然而,他的regexp不必要地复杂。根据您的请求,正如我的评论和其他人的评论所指出的,您绝对应该使用适当的XML解析器,如
xmlstartet
进行适当的XHTML解析。简单的regex不会验证遗留下来的内容
也就是说,对于您的示例(仅),要替换离开LOGIN
、PASSWORD
和Submit
的文本,您可以使用以下正则表达式:
sed "s/[#][{]i[.]m[[][']\([^']*\)['][]][}]/\1/" <file
查找正则表达式
-匹配英镑符号[#]
-匹配开口大括号[{]
-匹配i
'i'
-显式匹配[.]
字符(而不是。
任何字符)
-匹配m
'm'
-匹配开口括号[[]
-匹配单引号[']
-开始您的捕获组捕获要重新插入的文本作为反向引用\(
-匹配非单引号的零个或多个字符[^']*
-结束您的捕获组\)
-将单个引号匹配为下一个字符[']
-匹配右括号[]]
-匹配右大括号[}]
\(....\)
之间),可用作替换的replace
部分中的反向引用。在find
部分中可以有多个捕获组,您可以在替换的replace部分中将其引用为\1、\2、…
等等。在这里,查找部分中只有一个捕获组,所以不管怎样已匹配可以用作整个替换,例如
-用\1
[^']*
登录
、密码
和提交
,例如
sed "s/[#][{]i[.]m[[][']\([^']*\)['][]][}]/\1/" file
<h:panelGroup rendered="#{not accessBean.isUserLoggedIn}">
<h:form>
<p:panel style="margin-top:10px">
<table style="margin:10px">
<tbody>
<tr>
<td align="center">Login</td>
<td align="center">
<h:inputText value="#{accessBean.login}" />
</td>
</tr>
<tr>
<td align="center">Password</td>
<td align="center">
<h:inputSecret value="#{accessBean.password}" />
</td>
</tr>
</tbody>
</table>
<p:commandButton ajax="false" value="Submit" action="#{accessBean.login}" />
</p:panel>
</h:form>
</h:panelGroup>
sed“s/[\\][{]i[.]m[[[]]]\([^']*\)['][]][}]/\1/”文件
登录
密码
同样,作为免责声明和良好的常识,不要用正则表达式解析X/HTML,使用适当的工具,如
xmlstartet
。不要用正则表达式解析JSON,使用适当的工具来完成工作,如jq
——你明白了。(但对于这个有限的例子,正则表达式工作得很好,但它很脆弱,如果输入中有任何变化,它就会崩溃——这就是为什么我们有xmlstartet
和jq
)等工具的原因。首先选择正确的工具。我建议使用XML/HTML解析器(例如xmlstarlet)@Cyrus,谢谢你的回答。我刚刚更新了问题并删除了部分内容。虽然你肯定应该使用适当的XML解析器,比如xmlstartet
,来替换离开LOGIN
、PASSWORD
和Submit
的文本,但你可以使用以下正则表达式:sed“s/[#][{]I[.]m[[][']\([^']*\)['][]][}]/\1/“@DavidC.Rankin,请您将您的评论作为答案发布,以便我可以接受。您的解决方案非常有效。另外,如果您能解释一下这个表达方式,那将非常好。谢谢:-)