【问题标题】:How to match a single character except when on a specific situation除非在特定情况下,否则如何匹配单个字符
【发布时间】:2020-01-26 04:52:16
【问题描述】:

我有一个字符串,我想在每个分号 ; 处分成几部分。

我为此使用 JAVA String.split(regex),创建了一个字符串数组。

示例:

string 1;
string 2;
string 3;
string 4 (
   substring 1;
   substring 2;
   substring 3;
);
string 4;

我现在正在使用line.split("\\s*;\\s*");...

但是,正如预期但不想要的那样,让我回了["string 1", "string 2", "string 3", "string 4 (\nsubstring 1", "substring 2", "substring 3", ")", "string 4", ""]

那么我如何匹配每个;,以便我可以拆分它,除了括号内的那些(子字符串后面的那些)?

编辑:

我确实设法创建了一个正则表达式来匹配“;”在括号内,但不在括号外......但在使用逻辑并将~(a^b)转换为~av~b(德摩根定律)之后,我确实做了一个正则表达式来匹配“;”括号外。

但它仍然不起作用,并且仍然在每个分号中中断...是 Java 本身的问题吗?

当前模式:((?<![\S\s]*?\([\S\s]*?)|(?![\S\s]*?\)[\S\s]*?));

【问题讨论】:

  • ["string 1", "string 2", "string 3", "string 4 (substring 1; substring 2; substring 3)", "string 4", ""]
  • 这里是旧逻辑,但是为什么不将()之间的;值替换为另一个值(可以使用indexOf/substring),然后替换所有;然后重新替换步骤 1 中更改的值?
  • 我现在实际上正在尝试,但它不起作用。我正在检查,但我想知道如果我没有发现问题,我是否可以完全在正则表达式中做到这一点。 game = game.replaceAll("(?<=.*\\(.*);(?=.*\\).*)", "$semicolon$"); myStory.importStory(game, "\\s*;\\s*"); 有没有更好的方法来确定替换值?

标签: java regex string regex-lookarounds string-matching


【解决方案1】:

我确信一些 Java 专业人士有比正则表达式更好的解决方案,但这可能有点接近:

.*\((?:\s*(?:[^\r\n]*;)\s*)+\);|[^\r\n]+

我猜你可能想要trim 并将其推送到数组中。

测试

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class RegularExpression{

    public static void main(String[] args){

        final String regex = ".*\\((?:\\s*(?:[^\\r\\n]*;)\\s*)+\\);|[^\\r\\n]+";
        final String string = "string 1;\n"
             + "string 2;\n"
             + "string 3;\n"
             + "string 4 (\n"
             + "   substring 1;\n"
             + "   substring 2;\n"
             + "   substring 3;\n"
             + ");\n"
             + "string 4;\n"
             + "string 1;\n"
             + "string 2;\n"
             + "string 3;\n"
             + "string 4 (\n"
             + "   substring 1;\n"
             + "   substring 2;\n"
             + "   substring 3;\n"
             + ");\n"
             + "string 4;";

        final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
        final Matcher matcher = pattern.matcher(string);

        while (matcher.find()) {
            System.out.println("Full match: " + matcher.group(0));
            for (int i = 1; i <= matcher.groupCount(); i++) {
                System.out.println("Group " + i + ": " + matcher.group(i));
            }
        }

    }
}

输出

Full match: string 1;
Full match: string 2;
Full match: string 3;
Full match: string 4 (
   substring 1;
   substring 2;
   substring 3;
);
Full match: string 4;
Full match: string 1;
Full match: string 2;
Full match: string 3;
Full match: string 4 (
   substring 1;
   substring 2;
   substring 3;
);
Full match: string 4;

如果您希望简化/修改/探索表达式,在regex101.com 的右上角面板中已对此进行了说明。如果您愿意,您还可以在this link 中观看它如何与一些示例输入匹配。


【讨论】:

    【解决方案2】:

    使用这个:

    String[] array = line.split("(?<\!\\(.*[^)]);");
    

    代码如下:

    导入 java.util.Arrays;

    公共类测试{

    public static void main(String[] args) {
        String line = "string 1;" + 
                "string 2;" + 
                "string 3;" + 
                "string 4 (" + 
                "   substring 1;" + 
                "   substring 2;" + 
                "   substring 3;" + 
                ");" + 
                "string 4;";
        System.out.println(line);   
        System.out.println();
    
    
        String[] array = line.split("(?<!\\(.*[^)]);");
        System.out.println(
                Arrays.toString(array)); // Arrays.toString(Object[] a) converts an array to a printable string.
    
    
    }
    

    }

    打印:

    字符串 1;字符串 2;字符串 3;字符串 4(子字符串 1;子字符串 2;子字符串 3;);字符串 4;

    [字符串1,字符串2,字符串3,字符串4(子字符串1;子字符串2;子字符串3;),字符串4;]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-29
      • 2011-09-01
      • 2019-12-07
      • 2015-03-07
      • 1970-01-01
      • 2018-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多