Java replaceAll()&split()违规
我知道,我知道,现在我有两个问题,但这里的正则表达式意味着我不必编写两个复杂的循环。相反,我有一个只有我明白的正则表达式,我才会受雇于yonks。Java replaceAll()&split()违规
我有一个字符串,说stack.overflow.questions[0].answer[1].postDate
,我需要得到[0]和[1],最好在数组中。 “简单!”我的神经元惊叹,只需在输入字符串中使用正则表达式和split
方法;所以我想出了这个:
String[] tokens = input.split("[^\\[\\d\\]]");
这将产生以下:
[, , , , , , , , , , , , , , , , [0], , , , , , , [1]]
哦,亲爱的。所以,我想, “你会做replaceAll
在这种情况下?”:
String onlyArrayIndexes = input.replaceAll("[^\\[\\d\\]]", "");
它生产:
[0][1]
嗯。为什么这样?我正在寻找一个包含“[0]”作为第一个元素和“[1]”作为第二个元素的双元素字符串数组。为什么Split在这里不起作用,当Javadoc声明他们都使用Pattern类时,按照Javadoc?
总之,我有两个问题:为什么用split()
通话产生大阵与看似随意的空格字符和我是正确的思维中的replaceAll工作,因为正则表达式替换所有字符不匹配“[”一个数字和“]”?我错过了什么,这意味着我期望他们产生类似的输出(好吧,这是三个,请不要回答这个问题的线索?)。
很好的split
没有工作,它给你一个数组,用于存放每个匹配的字符串split,而不是一组中间带数字的括号。
至于replaceAll
我认为你的假设是正确的。它将删除所有内容(用""
替换该匹配项),这不是您想要的。
拆分此字符串周围的 给定的正则表达式匹配。
此方法的工作原理就好像调用 双参数拆分方法,其中 的给定表达式和极限参数 为零。尾随的空字符串是 因此不包含在 结果数组中。
字符串 “BOO:和:foo” 的,例如, 产生具有 以下结果这些表达式:由您提供的正则表达式定义的边界
Regex Result : { "boo", "and", "foo" } o { "b", "", ":and:f" }
这不是直接回答你的问题,但我想告诉你一个很好的API,将适合你的需要。
从谷歌Guava退房Splitter。
因此,对于你的榜样,你会使用这样的:
Iterable<String> tokens = Splitter.onPattern("[^\\[\\d\\]]").omitEmptyStrings().trimResults().split(input);
//Now you get back an Iterable which you can iterate over. Much better than an Array.
for(String s : tokens) {
System.out.println(s);
}
此打印: 0
1
一个很好的建议,谢谢。现在我只在这个特定的例子中使用正则表达式,但是如果我需要进一步的话,我会去番石榴。 – 2010-10-29 08:29:02
Google Guava支持正则表达式。正如我在示例中所展示的那样。 – 2010-10-29 08:30:48
split
分割,所以这并不令人惊讶,你得到很多条目 —几乎字符串中的所有字符都与你的正则表达式匹配,因此,根据定义,它们是出现分割的边界。
replaceAll
替换与您替换的正则表达式匹配,您的情况为空白字符串。
如果你试图抓住0
和1
,这是一个简单的循环:
String text = "stack.overflow.questions[0].answer[1].postDate";
Pattern pat = Pattern.compile("\\[(\\d+)\\]");
Matcher m = pat.matcher(text);
List<String> results = new ArrayList<String>();
while (m.find()) {
results.add(m.group(1)); // Or just .group() if you want the [] as well
}
String[] tokens = results.toArray(new String[0]);
或者,如果它是总是正是其中的两个:
String text = "stack.overflow.questions[0].answer[1].postDate";
Pattern pat = Pattern.compile(".*\\[(\\d+)\\].*\\[(\\d+)\\].*");
Matcher m = pat.matcher(text);
m.find();
String[] tokens = new String[2];
tokens[0] = m.group(1);
tokens[1] = m.group(2);
的问题是那split
这里是错误的操作。
在Ruby中,我会告诉你string.scan(/\[\d+\]/)
,这将使你的阵列["[0]","[1]"]
Java没有一个单一的方法相当,但我们可以用下面写一个scan
方法:
public List<String> scan(String string, String regex){
List<String> list = new ArrayList<String>();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(string);
while(matcher.find()) {
list.add(matcher.group());
}
return retval;
}
,我们可以把它作为scan(string,"\\[\\d+\\]")
等效Scala代码是:
"""\[\d+\]""".r findAllIn string
一个有趣的方法;谢谢! – 2011-07-04 08:00:53
谢谢,这是事实上,split为我的正则表达式的每个匹配给了我一个元素;这是我不明白的! – 2010-10-29 08:29:39