我是正则表达式的新手,我正在尝试用它来解析用“(”,“)”和空格分隔的标记。这是我的尝试:
String str = "(test (_bit1 _bit2 |bit3::&92;test#4|))";
String[] tokens = str.split("[\\s*[()]]");
for(int i = 0; i < tokens.length; i++)
System.out.println(i + " : " + tokens[i]);
我期待以下输出:
0:测试
1:_bit1
2:_bit2
3:| bit3 ::&amp; 92; test#4 |
但是,实际输出中会出现两个空标记:
0:
1:测试
2:
3:_bit1
4:_bit2
5:| bit3 ::&amp; 92;测试#4 |
我不明白为什么我在0和2位置有两个空标记。有人能给我一个提示吗?谢谢。
=====更新====
有Alan Moore的答案删除了它。但我喜欢这个答案,所以我把它复制在这里供我自己参考。
你的正则表达式,[\ s * [()]]匹配一个空格字符(\ s)或其中一个 字符*,(,或)。在开头的分隔符 string(()是你获得空的第一个令牌的原因。没有办法解决 那;你只需要检查一个空的第一个令牌并忽略它。
第二个空标记位于第一个空格和(第二个空格)之间 跟着它。那是你的,因为你使用了*(零或更多) 而不是+(一个或多个)。但修复它并不是那么简单。你要 在空间,parens或两者上分开,但你必须确保有 至少一个角色,无论哪个角色。这可能会这样做:
\ S * [()] + \ S * | \ S +
但你可能也应该在parens之间留出空格:
\ S *(?:[()] + \ S *)+ | \ S +
作为Java字符串文字,即:
\ S *(?:[()] + \ S *)+ | \ S +
答案 0 :(得分:3)
你的正则表达式错了,试试这个:
String [] tokens = str.split(&#34; [\ s(\)] +&#34;);
String[] tokens = str.split("[\\s()]+"); //At least one character
更新:我注意到你的代码实际上删除了括号,所以看起来你不必在括号之间转义它们......不知道为什么,任何人都可以回答这个问题?
新更新:感谢@AlanMoore的解释,因为我了解[]
中的括号并不需要转义。
答案 1 :(得分:2)
我的建议是,首先从两端删除分裂字符(以避免空字符串),然后进行分割。
String[] tokens = str.replaceAll("^[\\s()]+|[\\s()]+$", "").split("[\\s()]+");
-- replace leading or trailing--
另外,我已将您的分割字符(空格,(
)
)放在字符类[]
答案 2 :(得分:1)
您遇到的问题是它仍然在分隔符之间创建一个空字符串,然后在它到达分隔符后返回它。
您可以通过添加额外内容来了解我正在谈论的内容(例如:
String str = "(test (_bit1 (_bit2 |bit3::&92;test#4|))";
输出将变为:
0 :
1 : test
2 :
3 : _bit1
4 :
5 : _bit2
6 : |bit3::&92;test#4|
我建议使用以下代码:
String str = "(test (_bit1 (_bit2 |bit3::&92;test#4|))";
String[] tokensArray = str.split("[\\s[()]*]");
ArrayList<String> tokens = new ArrayList<>();
for (String token : tokensArray) {
if (!token.isEmpty()) {
tokens.add(token);
}
}
for (int i = 0; i < tokens.size(); i++)
System.out.println(i + " : " + tokens.get(i));
这样做是从阵列中删除任何空标记,因为这些标记被认为是“不正确”的标记。
答案 3 :(得分:0)
索引0是第一个(
之前的标记。索引2是空格与输入字符串中第二个(
之间的标记。
我认为你不能避开第一个,但你可以使用
来抑制第二个str.split("[\\s()]+");