标记化忽略转义字符的Java正则表达式

时间:2014-07-05 16:36:47

标签: java regex tokenize

考虑像

这样的测试字符串
Irrelevant start|group 1|group 2 with \| escaped|group 3|group 4|Irrelevant end

如何使用单个Java正则表达式解析它,以提取由条(|)分隔的所有组,同时忽略中间的转义栏(\ |),以及不相关的开始和结束部分(哪个不含酒吧?

earlier question中建议的断言后面的一个问题是,在Java中,它不允许变长字符串,并且上面提到的组没有预定义的

2 个答案:

答案 0 :(得分:2)

您可以使用split执行此操作。我们希望拆分|之前没有\的{​​{1}}。我们必须在正则表达式中转义|以匹配|,而不是将其用作or。要匹配我们正则表达式中的文字\(背后的负面看法),我们需要\\\\

import java.util.Arrays;

public class Test {

    public static void main(String[] args) {
        String str = "Irrelevant start|group 1|group 2 with \\| escaped|group 3|group 4|Irrelevant end";
        System.out.println(str);

        String[] arr = str.split("(?<!\\\\)\\|");

        String[] new_arr = Arrays.copyOfRange(arr, 1, arr.length - 1);
        System.out.println(Arrays.toString(arr));
        System.out.println(Arrays.toString(new_arr));

    }
}

输出:

Irrelevant start|group 1|group 2 with \| escaped|group 3|group 4|Irrelevant end
[Irrelevant start, group 1, group 2 with \| escaped, group 3, group 4, Irrelevant end]
[group 1, group 2 with \| escaped, group 3, group 4]

关于背后的负面看法的简单示例,让我们看一下(?<!a)b。这匹配b之前没有a的{​​{1}}。在我们的示例中,我们希望匹配文字\而不是a|而不是b,这就是为什么我们需要所有\ }。有很多资源可以环顾四周,但如果你想进一步阅读,here就是一个。


另外,鲍里斯蜘蛛指出这很脆弱,有些情况下它不会起作用。与使用正则表达式解析XML的方式类似,CSV格式通常应与解析库一起使用。

答案 1 :(得分:1)

除了马特的答案,我认为这是一个非常好的主意,如果你仍然对正则表达式感兴趣,你可以使用这个:

([\w ]+(\\\|[\w ]+)?)

您可以在这里查看一个有效的例子:

http://regex101.com/r/hK3fD3/1

正如您所看到的,每场比赛的每个第一组都包含相关内容,您可以丢弃第一场和最后一场比赛。

希望能提供帮助