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

时间:2013-05-20 18:21:26

标签: java regex split

我正在尝试在java中使用String split,以在子串之间拆分整个文档 标签空格和换行符,但我想排除引号之间存在单词的情况。

示例:

此文件

CATEGORYTYPE1
{
    CATEGORYSUBTYPE1
    {
        OPTION1 “ABcd efg1234”
        OPTION2 ABCdefg12345
        OPTION3 15
    }
    CATEGORYSUBTYPE2
    {
        OPTION1 “Blah Blah 123”
        OPTION2 Blah
        OPTION3 10
        OPTION4 "Blah"
    }
}

拆分为这些子字符串(如Eclipse调试器中所示):

[CATEGORYTYPE1, {, CATEGORYTYPE1, {, OPTION1, “ABcd, efg1234”, OPTION2....

当我使用我当前的正则表达式时:

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

    String[] tokens = data.split(regex);

但我想要实现的是将它拆分为:

[CATEGORYTYPE1, {, CATEGORYTYPE1, {, OPTION1, “ABcd efg1234”, OPTION2....

(不在引号之间拆分内容)

这可能与正则表达式有关吗?

3 个答案:

答案 0 :(得分:2)

以下是执行此操作的一种方法:

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将不会在拆分中使用,而外部匹配将匹配(因为后面跟着偶数个双引号字符)。

答案 1 :(得分:1)

在这里使用拆分似乎很复杂甚至不够,使用find更容易,试试这个:

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

如果您需要添加其他类型的引号(例如:“xxxxx xxxxx”),您可以轻松地将它们添加到模式中:

Pattern pattern = Pattern.compile("“[^”]+”|\"[^\"]+\"|\\S+");

您可以使用以下内容转发双引号("xxx \"xxx\""):

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

答案 2 :(得分:0)

我知道我加入派对的时间相当晚,但是如果你正在寻找一个花哨的正则表达式来“理解”转义",那么这个应该适合你:

Pattern p = Pattern.compile("(\\S*?\".*?(?<!\\\\)\")+\\S*|\\S+");
Matcher m = p.matcher(str);
while (m.find()) { ... }

它也会解析这样的事情:
ab "cd \"ef\" gh" ij "kl \"no pq\"\" rs"
于:
ab"cd \"ef\" gh"ij"kl \"no pq\"\" rs"(不会被奇数个转义引号(\")弄糊涂。

(可能不相关,但是这个也会在字符串中间“理解”",因此它会解析这个:ab c" "d ef到:ab,{{1} },c" "d - 并不是说​​这种模式很可能出现。)

无论如何,您还可以查看 short demo