Java 替换属性文件键中的所有空格

Java 替换属性文件键中的所有空格,java,regex,ant,Java,Regex,Ant,我想通过在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 w

我想通过在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="..."/>
或者我可以这样做
^([^=])|(\s))*(=.*)
来匹配不同的组,但是如何替换所有的空格,例如,如何重建结果以仅包含非空格

换句话说,给定如上所述的输入,如何在regex中执行以下伪代码:

  • 对于不以
    开头的行
  • 对于第一个
    =
    符号之前的所有字符
  • 将所有“”(空格)替换为“\”(正斜杠,空格)
一般来说,在正则表达式中,特别是在Java正则表达式中,这是可能的吗?(最好是ANT
replaceregexp
示例)

编辑:解决方案需要是正则表达式,不能涉及任何代码(很遗憾)。我知道如何使用代码来解决这个问题:)(不过谢谢你的建议),但我想先使用正则表达式解决方案(因为我使用的是ANT,所以需要编写一个自定义任务,我会尽量避免)

EDIT2根据伟大的答案,以下是工作ANT版本:

使用\G

<replaceregexp match="(\\G[^#= ]*) " replace="\1\\\\ " byline="true"... />
使用前向+后向

prop with spaces=value with spaces
#comment should not be replaced 
prop_without_spaces=value with spaces 2
一点也没有漏掉评论行(我觉得太过分了)


我不知道如何使用正则表达式,但是如果您阅读每一行,您可以执行
string.replaceAll(“,“\\”)
,为了避免注释行:

if(!string.startsWith("#"))
{
    string = string.replaceAll(" ", "\\ ");
}

我不了解ant,但如果它只是运行一个简单的
replaceAll
,那么您可以使用
\G
锚,它确保匹配是相邻的:

"((?:^|\\G)[^#= ]*) "
并将其替换为
“$1\\”
。最初我们可以忽略
\\G
选项。因此,我们只需找到一行的开头,然后继续,只要当前字符既不是空格,也不是注释,也不是值(
[^#=]*
)。然后我们匹配一个空间。空格前面的所有内容都被捕获到组1中,我们用
$1
写回,然后是反斜杠,然后是空格

现在,当matcher再次尝试匹配时,除了字符串的开头,它还可以在注释或值之前的任何行中继续它停止的位置(这仍然是一个感兴趣的位置)

当然,确保使用
m
修饰符使
^
匹配每行的开头

您可以执行以下操作:

  • 使用文件读取器读取文件的每一行
  • 对于每一行,使用子字符串将其拆分为两部分
  • 对于拆分的第一部分,应用正则表达式
  • 连接第一个公园和第二个公园
  • 或者,您可以使用split在一行中完成

    String s = "my name = abc is my name"
    System.out.println(s.split("=")[0].replaceAll("\\s", "") + " = " + s.split("=")[1]);
    

    希望有帮助

    不一定是最有效的,但您可以使用

    \s(?=.*=)
    

    这至少会限制它只匹配每行最后一个等号左边的空格(它不会完全跳过注释行,但只会转义包含等号的注释中的空格)。这可能足够,也可能不够,这取决于任何值是否包含等号。

    谢谢,但正如我在问答中所说的,它还将替换它需要的值,以替换关键部分中的所有空格…请参阅我的编辑。跳过以
    “#”开头的行的简单问题谢谢,仍然将替换值部分(在=号之后)。但是谢谢你的建议!因此,通过子字符串和连接来进行一些
    字符串
    拼接。这不是一个很难的问题…要求是一个纯正则表达式解决方案,抱歉混淆,更新了问题。谢谢!非常感谢,但我对纯正则表达式解决方案感兴趣:)在这种情况下,纯正则表达式解决方案只会使代码更加晦涩和难以维护。@StormeHowke您可能是对的,但让我先看看是否有纯正则表达式解决方案。。。由于我使用的是ANT,这意味着要编写一个自定义任务,我尽量避免使用。@EranMedan-不确定是否使用单个正则表达式,但您可以使用split,这可能无法解决您的目的,但另一种更简单的方法,请参阅edit.Hm。。。有意思,试试看!哦,是的,它起作用了!我只是想弄清楚它是如何工作的:)但是在我要求澄清之前,让我做一些家庭作业,谢谢!+1000因为
    \G
    也匹配行的开头,所以
    ^ |
    实际上不是多余的吗?这里有一个有趣的提示:您可以删除
    ^ |
    ,因为
    \G
    最初设置为输入的开始@EranMedan啊,很公平,如果您按行使用它,那么
    “(\\G[^#=]*)”
    确实很好。但当然,选择对你们来说最容易维护的。如果你想对你的正则表达式技能做点什么,你会让它飞涨吗它工作得很好。我可以接受带有=登录的转义注释,这是一个非常可读的选项。
    String s = "my name = abc is my name"
    System.out.println(s.split("=")[0].replaceAll("\\s", "") + " = " + s.split("=")[1]);
    
    \s(?=.*=)