使用正则表达式替换不在括号中的逗号

时间:2014-06-13 03:51:45

标签: java regex lookahead

我有这个字符串:

john(man,24,engineer),smith(man,23),lucy(female) 

如何用括号@替换括号中的逗号?

结果应为:

john(man,24,engineer)@smith(man,23)@lucy(female)

我的代码:

String str = "john(man,24,engineer),smith(man,23),lucy(female)";
Pattern p = Pattern.compile(".*?(?:\\(.*?\\)).+?");
Matcher m = p.matcher(str);
System.out.println(m.matches()+"  "+m.find());

为什么m.matches()为真且m.find()为假?我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:3)

使用否定前瞻来实现这一目标:

,(?![^()]*\))

说明:

,         # Match a literal ','
(?!       # Start of negative lookahead
  [^()]*  # Match any character except '(' & ')', zero or more times
  \)      # Followed by a literal ')'
)         # End of lookahead

Regex101 Demo

答案 1 :(得分:3)

如果遇到smiley:)escape\)

中的不平衡括号,则使用另一种方法的简单正则表达式

虽然前瞻方法有效(而且我也是粉丝),但它会因,smiley:)(man,23)之类的输入而中断,所以为了以防万一,我会给你一个替代的简单正则表达式。为了记录,由于潜在的嵌套,很难找到一种始终有效的简单方法。

这种情况与"regex-matching a pattern unless..."的这个问题非常相似。 我们可以用一个非常简单的正则表达式解决它:

\([^()]*\)|(,)

当然,我们可以通过允许左边匹配的括号滚过转义括号来避免更多的不愉快:

\((?:\\[()]|[^()])*\)|(,)

交替|的左侧匹配完成(parentheses)。我们将忽略这些匹配。右侧匹配并捕获第1组的逗号,我们知道它们是正确的逗号,因为它们与左侧的表达式不匹配。

此程序显示了如何使用正则表达式(请参阅online demo底部的结果):

import java.util.*;
import java.io.*;
import java.util.regex.*;
import java.util.List;

class Program {
public static void main (String[] args) throws java.lang.Exception  {

String subject = "john(man,24,engineer),smith(man,23),smiley:)(notaperson) ";
Pattern regex = Pattern.compile("\\([^()]*\\)|(,)");
Matcher m = regex.matcher(subject);
StringBuffer b= new StringBuffer();
while (m.find()) {
    if(m.group(1) != null) m.appendReplacement(b, "@");
    else m.appendReplacement(b, m.group(0));
}
m.appendTail(b);
String replaced = b.toString();
System.out.println(replaced);
} // end main
} // end Program

有关该技术的更多信息

How to match (or replace) a pattern except in situations s1, s2, s3...