使用高级正则表达式在java中拆分字符串

使用高级正则表达式在java中拆分字符串,java,regex,split,Java,Regex,Split,我尝试在java中使用字符串拆分,在子字符串之间拆分整个文档 制表符是空格和换行符,但我想排除引号之间存在单词的情况 例如: 这个文件 CATEGORYTYPE1 { CATEGORYSUBTYPE1 { OPTION1 “ABcd efg1234” OPTION2 ABCdefg12345 OPTION3 15 } CATEGORYSUBTYPE2 { OPTION1 “Blah Blah

我尝试在java中使用字符串拆分,在子字符串之间拆分整个文档 制表符是空格和换行符,但我想排除引号之间存在单词的情况

例如:

这个文件

CATEGORYTYPE1
{
    CATEGORYSUBTYPE1
    {
        OPTION1 “ABcd efg1234”
        OPTION2 ABCdefg12345
        OPTION3 15
    }
    CATEGORYSUBTYPE2
    {
        OPTION1 “Blah Blah 123”
        OPTION2 Blah
        OPTION3 10
        OPTION4 "Blah"
    }
}
拆分到这些子字符串(如Eclipse调试器中所示):

当我使用当前正则表达式时,如下所示:

    String regex = "([\\n\\r\\s\\t]+)";

    String[] tokens = data.split(regex);
但我想实现的是这样分割它:

[CATEGORYTYPE1, {, CATEGORYTYPE1, {, OPTION1, “ABcd efg1234”, OPTION2....
(不在引号之间拆分内容)


正则表达式可以这样做吗?怎么做?

在这里使用拆分似乎比较复杂,甚至不够,使用查找更容易,请尝试以下方法:

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

public class Main {
    public static void main(String[] argv) {

        List<String> result = new ArrayList<String>();

        Pattern pattern = Pattern.compile("\"[^\"]+\"|\\S+");
        Matcher m = pattern.matcher(yourstring);

        while (matcher.find()) {
            result.add(m.group(0));
        }
    }
}
您可以通过以下方式允许转义双引号(
“xxx\”xxx\“
):

Pattern pattern = Pattern.compile("\"(?:[^\"]+|(?<!\\)\")+\"|\\S+");

Pattern=Pattern.compile(“\”(?:[^\”])+|(?以下是一种方法:

str = "CATEGORYTYPE1\n" + 
"{\n" + 
"    CATEGORYSUBTYPE1\n" + 
"    {\n" + 
"        OPTION1 \"ABcd efg1234\"\n" + 
"        OPTION2 ABCdefg12345\n" + 
"        OPTION3 15\n" + 
"    }\n" + 
"    CATEGORYSUBTYPE2\n" + 
"    {\n" + 
"        OPTION1 \"Blah Blah 123\"\n" + 
"        OPTION2 Blah\n" + 
"        OPTION3 10\n" + 
"        OPTION4 \"Blah\"\n" + 
"    }\n" + 
"}\n";

String[] arr = str.split("(?s)(?=(([^\"]+\"){2})*[^\"]*$)\\s+");
System.out.println(Arrays.toString(arr));

// OUTPUT
[CATEGORYTYPE1, {, CATEGORYSUBTYPE1, {, OPTION1, "ABcd efg1234", OPTION2, ABCdefg12345, ...

说明:表示匹配空格或新行(
\s
),后跟偶数个双引号(
)。因此,在拆分中不会使用两个双引号字符之间的
\s
,而外部字符将匹配(因为它们后跟偶数个双引号字符).

我知道我入党很晚,但是如果您也在寻找一个花哨的正则表达式来“理解”转义
,这个应该适合您:

Pattern p = Pattern.compile("(\\S*?\".*?(?<!\\\\)\")+\\S*|\\S+");
Matcher m = p.matcher(str);
while (m.find()) { ... }
<代码>模式P=模式。编译(“\**\\”,*(?)在字符串的中间,因此它将解析:<代码> AB C”“D EF < /代码>到:<代码> AB <代码>,<代码> C”“D < /代码>,<代码> EF < /代码> -而不是这样的模式很可能出现。)
无论如何,您也可以看看这个

您最好使用一个成熟的解析器。我建议使用parboiled。我正在尝试编写我自己的:p
[\n\r\s\t]+
\s+
相同,因为
\s
包括所有
\n
\r
\t
\f
、空格、垂直标签。当你说“引号”时,你是指“正常”双引号(
)还是还包括
”、
等?关于转义引号呢,例如,您如何拆分:
abc“de\'fg”hi
?我只是在说双引号,但以上所有问题的答案都是非常好的。代码
模式。编译(“\”(\\\\\\\\\\\\\\\\\\\\\”*“\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
“另一个\“字符串”
。这个答案绝对是最好的!我现在只需要花一个小时来解码功夫忍者正则表达式!:P非常感谢!
str = "CATEGORYTYPE1\n" + 
"{\n" + 
"    CATEGORYSUBTYPE1\n" + 
"    {\n" + 
"        OPTION1 \"ABcd efg1234\"\n" + 
"        OPTION2 ABCdefg12345\n" + 
"        OPTION3 15\n" + 
"    }\n" + 
"    CATEGORYSUBTYPE2\n" + 
"    {\n" + 
"        OPTION1 \"Blah Blah 123\"\n" + 
"        OPTION2 Blah\n" + 
"        OPTION3 10\n" + 
"        OPTION4 \"Blah\"\n" + 
"    }\n" + 
"}\n";

String[] arr = str.split("(?s)(?=(([^\"]+\"){2})*[^\"]*$)\\s+");
System.out.println(Arrays.toString(arr));

// OUTPUT
[CATEGORYTYPE1, {, CATEGORYSUBTYPE1, {, OPTION1, "ABcd efg1234", OPTION2, ABCdefg12345, ...
Pattern p = Pattern.compile("(\\S*?\".*?(?<!\\\\)\")+\\S*|\\S+");
Matcher m = p.matcher(str);
while (m.find()) { ... }