【问题标题】:replacing regex in java string, which contains `
` symbol替换Java字符串中的正则表达式,其中包含` ` 符号
【发布时间】:2009-02-01 19:33:12
【问题描述】:

我必须通过java替换这个xml字符串的内容

<My:tag>value_1 22&#xA;value_2 54&#xA;value_3 11</My:tag>

所以,这个字符串是从一个 xml 中获取的,当我获取它时,我得到了这个结果:

<My:tag>value_1 22
value_2 54
value_3 11</My:tag>

如果我尝试用这种方式替换内容:

String regex =  "(<My:tag>)(.*)(</My:tag>)";
String new_string = old_string.replaceAll(regex,"<My:tag> new_stuff </My:tag>");

我没有得到任何结果。我认为是因为&amp;#xA; 符号

但是如果我尝试替换没有&amp;#xA; 符号的字符串,一切都会正常。

建议? 谢谢

【问题讨论】:

  • Giancarlo:我建议使用regex 标签,而不是regular-expressions,因为它更受欢迎(因此更多人会发现你的问题)。由于有 5 个标签的限制,而且 xA 不是人们会搜索的特定术语,我已将该标签替换为 regex 一个。

标签: java regex replace


【解决方案1】:

我不是 100% 确定 java 正则表达式引擎是如何工作的,但我无法想象一个实体会导致您的问题。您应该首先尝试简单地删除括号,因为您要替换整个表达式,而不是提取任何内容。

但是,如果您的实体实际上被转换为换行符,则可能导致它的原因可能是您的正则表达式不会捕获它,除非您明确地进行多行匹配。你也可以试试

[.\n]*

代替你的

.*

这可能是一个贪婪的竞标,并且回溯到很多匹配器来处理。不幸的是,我没有在这台机器上安装任何 java 的东西,所以我不能真正尝试和测试它。另一种可能性是积极寻找下一个左尖括号,如下所示:

[^<]* 

编辑:
正如您所建议的,我尝试了您的链接,并且以下操作完美:

表达式:

<My:tag>[^<]*</My:tag>

替换:

<My:tag> new_stuff </My:tag>

测试字符串:

<My:tag>value_1 22&#xA;value_2 54&#xA;value_3 11</My:tag>

【讨论】:

  • 这似乎不起作用,但是我不使用任何额外的库。如果你愿意,你可以在这里做一些实验fileformat.info/tool/regex.htm
  • Java 具有用于 DOTALL 模式的 (?s) 标志 - 启用。匹配换行符。确实 [.] 将匹配实际的 .不是任何字符。此外,[^>]* 将按预期工作,并且不会与词尾冲突。
  • 只是为了澄清 - 它应该是 [^]* 会起作用,但(我认为)会在回溯之前首先消耗所有结束标签,即没有那么好的表现。
  • '害怕你对 表示单词结尾,但 Perl、Java 和大多数其他风格使用 \b 表示单词开头或结尾。转义与否,尖括号只匹配尖括号。 regular-expressions.info/wordboundaries.html
  • 你说得对,\b 表示 Perl 和 java 中的字边界,\ 是 Posix-regex(我所说的“标准”,但也许我正在老的)。你对 perl 的看法是对的,我一定把它与分组括号混淆了(在 posix 中是转义括号,但在 perl 中不是)。
【解决方案2】:

我不明白为什么 &amp;#xA; 本身会导致任何问题 - 除非它在某个时候被转换为实际的换行符。

如果是这种情况,您需要启用 DOTALL 模式,以便 .也匹配换行符(默认情况下不匹配)。

要启用 DOTALL,只需以 (?s) 开头的表达式
(如果您创建了一个 Pattern 对象,您也可以将标志传递给它。)

不管怎样,试试这个:

String regex =  "(?s)(?<=<(My:tag)>).*?(?=</\1>)";
String new_string = old_string.replaceAll(regex,"new_stuff");


您还可以使用(?s:regex-segment) 为正则表达式的特定部分启用它,例如:

String regex =  "(?<=<(My:tag)>)(?s:.*?)(?=</\1>)";

【讨论】:

  • 是的,如果问题描述准确,则必须在应用正则表达式之前将实体替换为换行符。此外,您应该一直使用非贪婪的点星 (.*?),但是当您在 DOTALL 模式下进行匹配时,这一点更为重要。
  • 这有点模棱两可;我的意思是 GIANCARLO 应该像彼得在这里那样使用非贪婪的点星。
【解决方案3】:

我建议使用像 JDOMDOM4J 这样的 XML 库来操作 XML,而不是使用正则表达式。

【讨论】:

  • JDOM 和 DOM4J 如果您只需要进行一些文本操作,似乎有点矫枉过正。如果你需要做大规模的事情,你是对的,但是对于这个......不。
  • 没错,我只需要像这样操作字符串,我不认为是使用另一个库的情况......
  • 使用 XML 库的另一个优点是可以保证您的操作结果是格式良好的 XML——这就是(借口?)XML 的全部意义,不是吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-04
  • 2014-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 1970-01-01
相关资源
最近更新 更多