我有一个String,其中包含2或3个公司名称,每个名称都包含在括号中。每个公司名称也可以包含括号中的单词。我需要使用正则表达式将它们分开,但没有找到方法。
我的inputStr
(Motor (Sport) (racing) Ltd.) (Motorsport racing (Ltd.)) (Motorsport racing Ltd.)
or
(Motor (Sport) (racing) Ltd.) (Motorsport racing (Ltd.))预期结果是:
str1 = Motor (Sport) (racing) Ltd.
str2 = Motorsport racing (Ltd.)
str3 = Motorsport racing Ltd.我的代码:
String str1, str2, str3;
Pattern p = Pattern.compile("\\((.*?)\\)");
Matcher m = p.matcher(inputStr);
int index = 0;
while(m.find()) {
String text = m.group(1);
text = text != null && StringUtils.countMatches(text, "(") != StringUtils.countMatches(text, ")") ? text + ")" : text;
if (index == 0) {
str1= text;
} else if (index == 1) {
str2 = text;
} else if (index == 2) {
str3 = text;
}
index++;
}这对于str2和str3非常有用,但对str1却不起作用。
目前的结果:
str1 = Motor (Sport)
str2 = Motorsport racing (Ltd.)
str3 = Motorsport racing Ltd.发布于 2018-05-08 10:19:07
因此,我们可以假设括号最多可以嵌套在两个层次的深度。所以我们不需要太多的魔法就能做到。我会用下面的代码:
List<String> matches = new ArrayList<>();
Pattern p = Pattern.compile("\\([^()]*(?:\\([^()]*\\)[^()]*)*\\)");
Matcher m = p.matcher(inputStr);
while (m.find()) {
String fullMatch = m.group();
matches.add(fullMatch.substring(1, fullMatch.length() - 1));
}解释:
\\((?:...)*,我们将在括号中看到一些内容,然后再次看到一些非括号:\\([^()]*\\)[^()]* -重要的是我们不允许更多的括号在里面的括号\\)m.group();返回实际的完全匹配。fullMatch.substring(1, fullMatch.length() - 1)从开头和结尾删除括号。你也可以和另一个小组一起做。我只是不想让裁判更丑。发布于 2018-05-08 10:12:57
您可以不用regex来解决这个问题;请参考有关how to find the outermost parentheses的这个问题。
下面是一个示例:
import java.util.Stack;
public class Main {
public static void main(String[] args) {
String input = "(Motor (Sport) (racing) Ltd.) (Motorsport racing (Ltd.)) (Motorsport racing Ltd.)";
for (int index = 0; index < input.length(); ) {
if (input.charAt(index) == '(') {
int close = findClose(input, index); // find the close parentheses
System.out.println(input.substring(index + 1, close));
index = close + 1; // skip content and nested parentheses
} else {
index++;
}
}
}
private static int findClose(String input, int start) {
Stack<Integer> stack = new Stack<>();
for (int index = start; index < input.length(); index++) {
if (input.charAt(index) == '(') {
stack.push(index);
} else if (input.charAt(index) == ')') {
stack.pop();
if (stack.isEmpty()) {
return index;
}
}
}
// unreachable if your parentheses is balanced
return 0;
}
}输出:
Motor (Sport) (racing) Ltd.
Motorsport racing (Ltd.)
Motorsport racing Ltd.发布于 2018-05-08 10:30:22
为什么不直接用堆栈来解决呢?它只具有O(n)复杂度
'('时,将其推送到堆栈中,每次遇到')'时,就从堆栈中弹出。否则,将字符放入缓冲区。'('时是空的,那就意味着它在公司名称中,所以也要放在缓冲区中。')'放在缓冲区中,因为它是公司名称的一部分。https://stackoverflow.com/questions/50230897
复制相似问题