我想从字符串中提取数字:
String numbers[] = "M0.286-3.099-0.44c-2.901,-0.436,,,123,0.123,.34".split(PATTERN);
从这样的字符串中我想提取这些数字:
那是:
Float.parseFloat
可以解析的任何内容,因此.34
有效到目前为止我所拥有的:
String PATTERN = "([^\\d.-]+)|(?=-)";
这在某种程度上起作用,但显然远非完美:
,,,
如何修复PATTERN以使其有效?
答案 0 :(得分:3)
您可以使用这样的正则表达式:
([-.]?\d+(?:\.\d+)?)
<强> Working demo 强>
匹配信息:
MATCH 1
1. [1-6] `0.286`
MATCH 2
1. [6-12] `-3.099`
MATCH 3
1. [12-17] `-0.44`
MATCH 4
1. [18-24] `-2.901`
MATCH 5
1. [25-31] `-0.436`
MATCH 6
1. [34-37] `123`
MATCH 7
1. [38-43] `0.123`
MATCH 8
1. [44-47] `.34`
<强>更新强>
正如 Jawee 在他的评论中指出.34.34
存在问题,因此您可以使用他的正则表达式解决此问题。感谢Jawee指出这一点。
(-?(?:\d+)?\.?\d+)
要了解此正则表达式背后发生的事情,您可以查看Debuggex 图像:
引擎说明
1st Capturing group (-?(?:\d+)?\.?\d+)
-? -> matches the character - literally zero and one time
(?:\d+)? -> \d+ match a digit [0-9] one and unlimited times (using non capturing group)
\.? matches the character . literally zero and one time
\d+ match a digit [0-9] one and unlimited times
答案 1 :(得分:3)
试试这个(-?(?:\d+)?\.?\d+)
示例如下:
非常感谢 nhahtdh 的评论。这是真的,我们可以更新如下:
[-+]?(?:\d+(?:\.\d*)?|\.\d+)
实际上,如果我们采用所有可能的浮点输入字符串格式(例如:Infinity
,-Infinity
,00
,0xffp23d
,88F
),那么它可能有点复杂。但是,我们仍然可以在Java代码下面实现它:
String sign = "[-+]?";
String hexFloat = "(?>0[xX](((\\p{XDigit}+)\\.?)|((\\p{XDigit}*)\\.(\\p{XDigit}+)))[pP]([-+])?(\\p{Digit}+)[fFdD]?)";
String nan = "(?>NaN)";
String inf = "(?>Infinity)";
String dig = "(?>\\d+(?:\\.\\d*)?|\\.\\d+)";
String exp = "(?:[eE][-+]?\\d+)?";
String suf = "[fFdD]?";
String digFloat = "(?>" + dig + exp + suf + ")";
String wholeFloat = sign + "(?>" + hexFloat + "|" + nan + "|" + inf + "|" + digFloat + ")";
String s = "M0.286-3.099-0.44c-2.901,-0.436,,,123,0.123d,.34d.34.34M24.NaNNaN,Infinity,-Infinity00,0xffp23d,88F";
Pattern floatPattern = Pattern.compile(wholeFloat);
Matcher matcher = floatPattern.matcher(s);
int i = 0;
while (matcher.find()) {
String f = matcher.group();
System.out.println(i++ + " : " + f + " --- " + Float.parseFloat(f) );
}
然后输出如下:
0 : 0.286 --- 0.286
1 : -3.099 --- -3.099
2 : -0.44 --- -0.44
3 : -2.901 --- -2.901
4 : -0.436 --- -0.436
5 : 123 --- 123.0
6 : 0.123d --- 0.123
7 : .34d --- 0.34
8 : .34 --- 0.34
9 : .34 --- 0.34
10 : 24. --- 24.0
11 : NaN --- NaN
12 : NaN --- NaN
13 : Infinity --- Infinity
14 : -Infinity --- -Infinity
15 : 00 --- 0.0
16 : 0xffp23d --- 2.13909504E9
17 : 88F --- 88.0
答案 2 :(得分:2)
使用您自己制作的正则表达式,您可以按如下方式解决:
String[] numbers = "M0.286-3.099-0.44c-2.901,-0.436,,,123,0.123,.34"
.replaceAll(PATTERN, " ")
.trim()
.split(" +");
另一方面,如果我是你,我会改为循环:
Matcher m = Pattern.compile("[.-]?\\d+(\\.\\d+)?").matcher(input);
List<String> matches = new ArrayList<>();
while (m.find())
matches.add(m.group());
答案 3 :(得分:2)
你可以在一行中完成(但比aioobe的答案少一步!):
String[] numbers = "M0.286-3.099-0.44c-2.901,-0.436,,,123,0.123,.34"
.replaceAll("^[^.\\d-]+|[^.\\d-]+$", "") // remove junk from start/end
.split("[^.\\d-]+"); // split on anything not part of a number
虽然拨打电话的次数较少,但aioobe的答案更容易阅读和理解,这使他的代码更好。
答案 4 :(得分:1)
我认为这正是你想要的:
String pattern = "[-+]?[0-9]*\\.?[0-9]+";
String line = "M0.286-3.099-0.44c-2.901,-0.436,,,123,0.123,.34";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(line);
List<String> numbers=new ArrayList<String>();
while(m.find()) {
numbers.add(m.group());
}
答案 5 :(得分:0)
你很高兴为此付出了赏金。
不幸的是,正如您可能已经知道的那样,这不能使用
完成
直接使用Java的字符串拆分方法。
如果不能直接完成,那么就没有理由把它弄得一团糟,好吧......一块垃圾。
原因很多,有些相关,有些没有。
首先,你需要定义一个好的正则表达式作为基础 这是我所知道的唯一一个将验证并提取正确形式的正则表达式:
# "((?=[+-]?\\d*\\.?\\d)[+-]?\\d*\\.?\\d*)"
( # (1 start)
(?= [+-]? \d* \.? \d )
[+-]? \d* \.? \d*
) # (1 end)
所以,看看这个基础正则表达式,很明显你想要这个匹配的形式 在拆分的情况下,您不要想要这个匹配的表单,因为那个&#39; 你想要休息的地方。
当我看到Java的分裂时,我发现无论匹配什么,它都会被排除在外 从结果数组。
因此,假设分割使用,匹配(和消费)的第一件事是所有不是的东西 这个。那部分将是这样的:
(?:
(?!
(?= [+-]? \d* \.? \d )
[+-]? \d* \.? \d*
)
.
)+
由于唯一剩下的是有效十进制数字,下一个休息时间将在某处 有效数字之间。这部分添加到第一部分,将是这样的:
(?:
(?!
(?= [+-]? \d* \.? \d )
[+-]? \d* \.? \d*
)
.
)+
| # or,
(?<=
(?= [+-]? \d* \.? \d )
[+-]? \d* \.? \d*
)
(?=
(?= [+-]? \d* \.? \d )
[+-]? \d* \.? \d*
)
突然之间,我们遇到了一个问题.. 一个可变长度的后视断言
所以,它的游戏结束了整个事情。
最后,不幸的是,Java(据我所知)并没有提供包含捕获的规定 组内容(在正则表达式中匹配)作为结果数组中的元素 Perl确实如此,但我无法在Java中找到这种能力。
如果Java有这样的规定,可以将break子表达式组合起来进行无缝拆分 像这样:
(?:
(?!
(?= [+-]? \d* \.? \d )
[+-]? \d* \.? \d*
)
.
)*
(
(?= [+-]? \d* \.? \d )
[+-]? \d* \.? \d*
)