我想通过在Java属性文件中包含空格的所有键之前添加来转义它们
示例输入
prop with spaces=value with spaces
#comment should not be replaced
prop_without_spaces=value with spaces 2
所需输出:
prop with spaces=value with spaces
#comment should not be replaced
prop_without_spaces=value with spaces 2
我知道我可以用替换所有空格
<replaceregexp byline="true" flags="g" match="s" replace="\\ " file="..."/>
但它将这个结果呈现为
prop with spaces=value with spaces
#comment should not be replaced
prop_without_spaces=value with spaces 2
或者我可以做一些类似于^(([^=])|(s))*(=.*)
的事情来匹配各个组,但我如何替换所有空间,例如,我如何重建结果以仅包括非空间?
换句话说,给定如上所述的输入,我如何在regex中执行以下伪代码:
- 对于不以
#
开头的行 - 对于第一个
=
符号之前的所有字符 - 将所有"(空格)替换为"\"(正斜杠,空格)
这在一般的RegEx中,特别是在Java RegEx中可能吗?(优选ANT replaceregexp
示例)
EDIT:解决方案需要是RegEx表达式,不能涉及任何代码(不幸的是)。我知道如何使用代码来解决这个问题:)(谢谢你的建议),但我正试图首先使用RegEx解决方案(因为我使用的是ANT,所以需要编写一个自定义任务,我尽量避免)。
EDIT2基于这些不错的答案,以下是正在运行的ANT版本:
使用\G
<replaceregexp match="(\G[^#= ]*) " replace="1\\ " byline="true"... />
使用前瞻
逃离有=
登录的评论
<replaceregexp match="(s)(?=.*=)" replace="\\ " ... />
使用lookahead+lookbacking
根本无法逃脱评论行(我认为这太夸张了)
<replaceregexp match="(?<!#[^=]{0,100})(s)(?=.*=)" replace="\\ " ... />
我不关心ant,但如果它只是通过一个简单的replaceAll
运行,那么您可以使用G
锚点,它可以确保匹配是相邻的:
"((?:^|\G)[^#= ]*) "
并将其替换为"$1\ "
。最初,我们可以忽略\G
备选方案。因此,我们只需尝试找到一行的开头,然后继续,只要当前字符既不是空格,也不是注释的开头,也不是值([^#= ]*
)。然后我们匹配一个空格。空间前面的所有内容都被捕获到组1中,我们用$1
、一个反斜杠和一个空格将其写回。
现在,当匹配器尝试再次匹配时,除了字符串的开头,它还可以在注释或值之前的任何一行中继续它停止的位置(这仍然是一个感兴趣的位置)。
当然,请确保使用m
修饰符使^
与每行的开头匹配。
工作演示。
不一定是最有效的,但您可以使用的match
表达式
s(?=.*=)
这至少会限制它只匹配每行最后一个等号左边的空格(它不会完全跳过注释行,但只会转义包含等号的注释中的空格)。根据值是否包含等号,这可能足够也可能不够。
我不知道用正则表达式做这件事,但如果你阅读每一行,你可以做string.replaceAll(" ", "\ ")
,并避免注释行:
if(!string.startsWith("#"))
{
string = string.replaceAll(" ", "\ ");
}
您可以执行以下操作:
- 使用FileReader读取文件的每一行
- 对于每一行,
=
使用子字符串将其拆分为两部分 - 对于拆分的第一部分,应用正则表达式
- 将第一个园区与第二个园区连接起来
或者,您可以使用split在一行中完成。
String s = "my name = abc is my name"
System.out.println(s.split("=")[0].replaceAll("\s", "") + " = " + s.split("=")[1]);
希望它能有所帮助!!