忽略模式的字符串分割正则表达式

4

我有一个源字符串,想要分离出其中的 data

String source = "data|junk,data|junk|junk,data,data|junk";
String[] result = source.split(",");

上述代码输出了 data|junk、data|junk|junk、data、data|junk。为了进一步提取数据,我执行了以下操作:
for (int i = 0; i < result.length; i++) {
    result[i] = result[i].split("\\|")[0];
}

我想要的是数据,数据,数据,数据。我想看看是否可以使用正确的正则表达式一次性拆分它:

String[] result = source.split("\\|.*?,");

上面的代码输出是data, data, data, data|junk,其中最后两个"data"没有被分割。请问你能否提供正确的正则表达式来得到我想要的结果吗?
示例字符串:"Ann|xcjiajeaw,Bob|aijife|vdsjisdjfe,Clara,David|rijfidjf"
期望结果:"Ann, Bob, Clara, David"

如果 source = "data|junk, junk|junk",你的结果将是 String[0] = "data",String[1] = null 或者 String[1] = "junk"? - Jun Rikson
没有像这样的源。第一个“|”之前的所有部分都是我想要的数据。或者如果没有带有“|” 的多部分,则逗号之间的整个部分是数据。 - user1589188
3个回答

3
你可以修改正则表达式以解决“垃圾”问题,然后在匹配数据的同时继续匹配:
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class RegexTest {
    public static void main(String[] args) {
        String input = "Ann|xcjiajeaw,Bob|aijife|vdsjisdjfe,Clara,David|rijfidjf";
        Pattern p = Pattern.compile("(\\w+)(\\|\\w+)*,?");
        Matcher m = p.matcher(input);
        while (m.find()) {
            System.out.println(m.group(1));
        }
    }
}

正则表达式查找单词字符(字母、数字和下划线)并捕获该字符。然后查找一个管道符号(以转义的形式出现,以免在正则表达式中具有特殊含义),后面再加上单词字符。这个管道符及单词字符可以出现任意次数(零到多次)。之后可能会有一个逗号,但不是必须的。
这会打印出:
"Ann" "Bob" "Clara" "David"
它还会捕获“junk”,在循环中可以通过`m.group(2)`访问。如果您不想捕获它,请在正则表达式中插入 `?:`。
Pattern.compile("(\\w+)(?:\\|\\w+)*,?");

1
啊,好的,使用捕获组会起作用。但我不能直接将其用作拆分的正则表达式。由于我正在寻找一个拆分正则表达式,所以我会选择另一个作为答案。但对于其他想要使用捕获组的人来说,这里肯定有很棒的信息。非常感谢。 - user1589188

2
在这个字符串中,
Ann|xcjiajeaw,Bob|aijife|vdsjisdjfe,Clara,David|rijfidjf
使用正则表达式\\|.*?,可以匹配到|任意非逗号字符串,,但是它不能匹配最后的|rijfidjf,因为它不是以逗号结尾的。所以要用(,|$)代替,,使正则表达式变成\\|.*?(,|$)才能匹配到。
但是上面的正则表达式无法匹配单独的逗号,所以将,\\|.*?(,|$)交替使用,就得到了最终的正则表达式: (\\|.*?(,|$)|,) 模式(\\|.*?(,|$)|,)可以有效匹配这个字符串。
String source = "Ann|xcjiajeaw,Bob|aijife|vdsjisdjfe,Clara,David|rijfidjf";
String[] result = source.split("(\\|.*?(,|$)|,)");
for (int i = 0; i < result.length; i++) {
    System.out.println(result[i]);
}

输出:

Ann
Bob
Clara
David

1
谢谢。我喜欢你的答案最短。如果你能添加一些解释,让我知道如何组合或想出这个正则表达式,那么我会选择你的答案作为最佳答案。 - user1589188

1
我想出了以下解决方案:
String source = "one|junk,two|junk|junk,three,four|junk|junk";
String[] result = source.split("([|](?:(.*?,(?=[^,]+[|,]|$))|.*$))|,");
System.out.println(Arrays.toString(result));

[one, two, three, four]

谢谢!这个也可以。但是@boobalan的答案更短,我想我会选择他的。 - user1589188
@user1589188 是的,他的回答非常聪明。可悲的是,这是我能做到的最好的了。 - Tim Biegeleisen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接