当前位置: 首页 > 知识库问答 >
问题:

用于分隔括号内字符串的正则表达式[重复]

朱俭
2023-03-14

我有一个字符串,其中包含2或3个公司名称,每个名称用括号括起来。每个公司名称也可以包含括号中的单词。我需要用正则表达式将它们分开,但没有找到方法。

我的输入代码:

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

这适用于str2str3,但不适用于str1

当前结果:

str1 = Motor (Sport)
str2 = Motorsport racing (Ltd.)
str3 = Motorsport racing Ltd.

共有3个答案

韩博厚
2023-03-14

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

>

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));
}
何睿范
2023-03-14

所以我们可以假设括号最多可以嵌套两层。所以我们可以不用太多魔法就能做到。我会使用以下代码:

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)删除了开头和结尾的括号。您也可以使用其他组。我只是不想让正则表达式变得更丑。
房学
2023-03-14

你可以不用正则表达式解决这个问题;关于如何找到最外面的括号,请参考这个问题。

下面是一个例子:

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.
 类似资料:
  • 上面的正则表达式返回括号之间的文本。 如: 如何重写上面的正则表达式,所以我提供了一个类似的字符串,它将返回。i、 e带括号的部分,其中包含大括号中的字符串。

  • 这是我之前问题的后续。我意识到我需要更具体地说明我的regex案例,以获得适用于我的案例的答案。 我已经与这个正则表达式斗争了很长一段时间(也使用我上一个问题的答案),我似乎无法构建我需要的东西。 我需要将所有字符串中出现的两个重复出现的单引号替换为(因此字符串内部意味着单引号)。这是因为在一种语言(语法)中,字符串中的引号使用<code>‘转义。 这里有一个例子(实际的例子可以包含用< code

  • 我想将“word1和word2或(word3和(word4或word5))和word6”等字符串与“和”分开,以便从括号外获得:“word1”“word2或(word3和(word4或word5))”“word6” 请注意,括号组可以包含许多其他括号组。 我做了一些研究,我发现了一个正则表达式,它与我想要的相反:这个正则表达式选择括号之外的“AND”以外的所有内容。我还尝试了前瞻和后视,但没有成功

  • 我想将一个长数组值转换为一个特定格式的字符串。 例如,将longArray={0,1,2,3}转换为字符串0.1.2.3 我可以执行arrays.ToString(longArray),它将返回[0,1,2,3]。 现在必须将字符串[0,1,2,3]转换为0.1.2.3

  • 问题内容: 当我使用某种方式时,它仍然会触发,好像连字符无效。我试着和 问题答案: 转义使用应该没问题,但是您也可以尝试将其放在字符类的开头或结尾。这应该为您工作:

  • 我有一个表格形式的命令输出。我正在解析结果文件的输出并将其存储在字符串中。一行中的每个元素由一个或多个空格字符分隔,因此我使用正则表达式匹配1个或多个空格并拆分它。但是,在每个元素之间插入一个空格: 还有更好的方法吗? 每次拆分后,str2都会附加到列表中。