用于分隔括在括号中的字符串的正则表达式

Eqr*_*444 10 java regex string

我有一个String包含2或3个公司名称,每个名称都括在括号中.每个公司名称也可以包含括号中的单词.我需要使用正则表达式将它们分开,但没有找到.

我的inputStr:

(Motor (Sport) (racing) Ltd.) (Motorsport racing (Ltd.)) (Motorsport racing Ltd.)
or 
(Motor (Sport) (racing) Ltd.) (Motorsport racing (Ltd.))
Run Code Online (Sandbox Code Playgroud)

预期的结果是:

str1 = Motor (Sport) (racing) Ltd.
str2 = Motorsport racing (Ltd.)
str3 = Motorsport racing Ltd.
Run Code Online (Sandbox Code Playgroud)

我的代码:

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++;
}
Run Code Online (Sandbox Code Playgroud)

这伟大工程str2str3,但不适合str1.

目前的结果:

str1 = Motor (Sport)
str2 = Motorsport racing (Ltd.)
str3 = Motorsport racing Ltd.
Run Code Online (Sandbox Code Playgroud)

孙兴斌*_*孙兴斌 9

没有正则表达式就可以解决这个问题; 请参阅此问题,了解如何找到最外面的括号.

这是一个例子:

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

输出:

Motor (Sport) (racing) Ltd.
Motorsport racing (Ltd.)
Motorsport racing Ltd.
Run Code Online (Sandbox Code Playgroud)

  • @ifloop在语法层面上,你是对的.关于解决问题的方法,我不同意.替代方法很有用.您可能想要查看这篇关于SO不受欢迎的元文章:https://meta.stackoverflow.com/questions/366692/how-do-you-know-stack-overflow-feels-unwelcoming (6认同)
  • @ifloop即使方法B比方法A更有效? (2认同)

Tam*_*Rev 7

因此我们可以假设括号最多可以嵌套两个级别.所以我们可以毫不费力地做到这一点.我会使用这段代码:

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));
}
Run Code Online (Sandbox Code Playgroud)

说明:

  • 首先我们匹配一个括号: \\(
  • 然后我们匹配一些非括号字符:[^()]*
  • 零次或多次:(?:...)*我们将在括号内看到一些内容,然后再看一些非括号:
  • \\([^()]*\\)[^()]* - 重要的是我们不允许在括号内添加任何括号
  • 然后是右括号: \\)
  • m.group(); 返回实际的完整匹配.
  • fullMatch.substring(1, fullMatch.length() - 1)从开头和结尾删除括号.你也可以和另一个团队一起做.我只是不想让正则表达式更加丑陋.


Nap*_*ook 6

为什么不用堆栈解决它?它只有O(n)复杂度

  1. 只需解析字符串,每次遇到一个字符串'(',将其推送到堆栈,每次遇到一个')',从堆栈弹出.否则,将字符放在缓冲区中.
  2. 如果在推送a时堆栈为空,'('则表示它是公司名称,因此也将其放入缓冲区.
  3. 类似地,如果在弹出后堆栈不为空,则将其放入')'缓冲区中,因为它是公司名称的一部分.
  4. 如果在弹出后堆栈为空,则表示第一个公司名称已结束,缓冲区值为公司名称并清除缓冲区.

    String string = "(Motor (Sport) (racing) Ltd.) (Motorsport racing (Ltd.)) (Motorsport racing Ltd.)";
    List<String> result = new ArrayList();
    StringBuffer buffer = new StringBuffer();
    
    Stack<Character> stack = new Stack<Character>();
    for (int j = 0; j < string.length(); j++) {
        if (string.charAt(j) == '(') {
            if (!stack.empty())
                buffer.append('(');
            stack.push('(');
        } else if (string.charAt(j) == ')') {
            stack.pop();
            if (stack.empty()) {
                result.add(buffer.toString());
                buffer = new StringBuffer();
            }else
                buffer.append(')');
        }else{
            buffer.append(string.charAt(j));
        }
    }
    
    for(int i=0;i<result.size();i++){
        System.out.println(result.get(i));
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • @ifloop很酷,你解释了你的-1.然而,这种评论和-1-s使SO成为一个不受欢迎的地方.我认为发布开箱即用的答案是可以的.有时这些是流行的答案,即当OP想用正则表达式解析xml时. (6认同)