所以,最初,我认为这不能用正则表达式来完成。我的假设是错误的,但这只能通过删除重复项和空字符串/空值来实现。
正则表达式
See regex in use here
(?=(\d+[.,]\d{2}))(?=((?:\d+[.,]){2,}?\d{2})?)(?=((?:\d+[.,])+\d{2}))
上面的模式包含 3 个正向前瞻。它们如下:
-
(?=(\d+[.,]\d{2})) 确保以下匹配
-
(\d+[.,]\d{2}) 将以下内容捕获到捕获组 1。这将捕获较短的变体,例如 1.23。
-
\d+ 匹配一位或多位数字
-
[.,] 匹配 . 或 , 字面意思
-
\d{2} 精确匹配 2 位数字
-
(?=((?:\d+[.,]){2,}?\d{2})?) 确保以下匹配
-
((?:\d+[.,]){2,}?\d{2})? 可以选择将以下内容捕获到捕获组 2。这将捕获 中间 数字,例如 1.234,56,其中较小版本和较长版本存在于同一位置(1.23 和 1.234,567.89分别)。如果可能有更长的数字版本,您可能需要添加更多与此相同的正向预测,并将下一节中的{2,} 更改为{3,}、{4,} 等,并将这些组添加到while 循环中。如果不存在 in-between 数字,它将简单地捕获与第三次前瞻相同的内容(代码中删除了重复项)。
-
(?:\d+[.,]){2,}? 匹配以下 2 次或更多次,但越少越好。
-
\d+ 匹配一位或多位数字
-
[.,] 匹配 . 或 , 字面意思
-
\d{2} 精确匹配 2 位数字
-
(?=((?:\d+[.,])+\d{2})) 确保以下匹配
-
((?:\d+[.,])+\d{2}) 将以下内容捕获到捕获组 3。这将捕获更长的变体,例如 1.234,567.89。
-
(?:\d+[.,])+ 匹配以下1次或多次
-
\d+ 匹配一位或多位数字
-
[.,] 匹配 . 或 , 字面意思
-
\d{2} 精确匹配 2 位数字
代码
下面的代码简单地遍历所有匹配项并提取组值并将它们添加到List。然后使用here 找到的方法从列表中删除null 值。然后将该列表转换为Set 以根据this answer 删除重复项并添加回(现在为空)列表。
See code in use here
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main{
public static void main(String[] args) {
String s = "1.234,567.89";
Pattern p = Pattern.compile("(?=(\\d+[.,]\\d{2}))(?=((?:\\d+[.,]){2,}?\\d{2})?)(?=((?:\\d+[.,])+\\d{2}))");
Matcher m = p.matcher(s);
List<String> al = new ArrayList<>();
Set<String> hs = new HashSet<>();
while(m.find()) {
al.add(m.group(1));
al.add(m.group(2));
al.add(m.group(3));
}
al.removeAll(Collections.singleton(null));
hs.addAll(al);
al.clear();
al.addAll(hs);
System.out.println(al);
}
}
结果
下面结果中的数字与 OP 的值列表一致(尽管输出看起来不同,您可以通过交叉检查两组值来确认)。
[34,567.89, 4,56, 7.89, 234,56, 4,567.89, 1.234,56, 1.23, 1.234,567.89, 34,56, 567.89, 67.89, 234,567.89]