正则表达式积极lookbehind灾难
我的目标是匹配第一个0和零后十进制值的所有内容。如果第一个小数位是零,那么我也想匹配小数点。如果没有小数点,则不捕获任何数据。正则表达式积极lookbehind灾难
这里有我想要的一些例子:
180.57// should capture the "0123" on the end
180.570 // should capture the "0" on the end
180.// should capture the ".0123" on the end
180.0 // should capture the ".0" on the end
18// should capture nothing
180 // should capture nothing
如果小数点后第一位是0,则使得比赛很简单:
(\.0.*)
我的问题是第一位小数时匹配地方不是0.我相信积极lookbehind将解决这个问题,但我无法让它正常工作。这里是我尝试过的一个正则表达式:
(?<=^.*\..*)0.*
这个正则表达式最终将在Java中使用。
UPDATE:
我要使用这个表达式摆脱数字的和可能的小数点上使用Java的replaceAll
方法的字符串的结尾。我将通过用空字符串替换捕获组来完成此操作。这是我想要的更好的例子。
String case1 = "180.570123";
String case2 = "180.570";
String case3 = "180.0123";
String case4 = "180.0";
String case5 = "180123";
String case6 = "180";
String result = null;
result = case1.replaceAll("THE REGEX I NEED", "");
System.out.println(result); // should print 180.57
result = case2.replaceAll("THE REGEX I NEED", "");
System.out.println(result); // should print 180.57
result = case3.replaceAll("THE REGEX I NEED", "");
System.out.println(result); // should print 180
result = case4.replaceAll("THE REGEX I NEED", "");
System.out.println(result); // should print 180
result = case5.replaceAll("THE REGEX I NEED", "");
System.out.println(result); // should print 18
result = case6.replaceAll("THE REGEX I NEED", "");
System.out.println(result); // should print 180
测试这些regexs您可以使用此表达式:
\.[1-9]*(0\d*)
你想将是第一个捕获组中的内容。 (除小数点)
如果你想捕捉到小数点也一样,你可以使用:
(?:\.[1-9]+|(?=\.))(\.?0\d*)
例(online):
Pattern p = Pattern.compile("(?:\\.[1-9]+|(?=\\.))(\\.?0\\d*)");
String[] strs = {"180.570123", "180.570", "180.0123", "180.0", "180123", "180", "180.2030405"};
for (String s : strs) {
Matcher m = p.matcher(s);
System.out.printf("%-12s: Match: %s%n", s,
m.find() ? m.group(1) : "n/a");
}
输出:
180.57: Match:
180.570 : Match: 0
180.: Match: .
180.0 : Match: .0
18: Match: n/a
180 : Match: n/a
180.2030405 : Match: 030405
后视可能是矫枉过正。这一个行之有效 - >
/\.\d*(0\d*)/
错误地捕获了案例1,根本没有捕获案例2,3或4。 – ubiquibacon 2012-03-02 14:15:48
但不是这种情况下捕获小数点和以下0.你期望在这里:'180.0407' – Ethan 2012-03-02 14:17:14
该组捕获你想要的,除了.0的情况。 – Ethan 2012-03-02 14:18:04
我会写一个小功能做的提取,而不是正则表达式。
private String getZeroPart(final String s) {
final String[] strs = s.split("\\.");
if (strs.length != 2 || strs[1].indexOf("0") < 0) {
return null;
} else {
return strs[1].startsWith("0") ? "." + strs[1] : strs[1].substring(strs[1].indexOf("0"));
}
}
来测试它:
final String[] ss = { "180.570123", "180.570", "180.0123",
"180.0", "180123", "180", "180.2030405","180.5555" };
for (final String s : ss) {
System.out.println(getZeroPart(s));
}
输出:
0
.
.0
null
null
030405
null
更新
基于问题的编辑。做的方法的一些变化,以获得正确的数字:
private String cutZeroPart(final String s) {
final String[] strs = s.split("\\.");
if (strs.length != 2 || strs[1].indexOf("0") < 0) {
return s;
} else {
return strs[1].startsWith("0") ? strs[0] : s.substring(0, strs[0].length() + strs[1].indexOf("0") + 1);
}
}
输出:
180.57-> 180.57
180.570 -> 180.57
180.-> 180
180.0 -> 180
18-> 18
180 -> 180
180.2030405 -> 180.2
180.5555 -> 180.5555
谢谢你。这是很好的选择,但我认为正则表达式有点干净:) – ubiquibacon 2012-03-02 16:54:17
你可以试试这个:
Matcher m = Pattern.compile("(?<=(\\.))(\\d*?)(0.*)").matcher("180.2030405");
String res="";
if(m.find()){
if(m.group(2).equals("")){
res = "."+m.group(3);
}
else{
res = m.group(3);
}
}
捕获情况1错误,不捕捉的情况下2或者4。 – ubiquibacon 2012-03-02 14:10:20
@typoknig,已更新。案例1总是匹配正确。 *使用第一个捕获组的内容,而不是整个匹配。* – Qtax 2012-03-02 14:14:39
啊,我明白了。正如你所说的那样,在使用第一个捕获组的内容时它似乎工作正常。非常感谢! – ubiquibacon 2012-03-02 14:54:04