java Regex:如何找到前面没有空格和逗号的实数

Posted

技术标签:

【中文标题】java Regex:如何找到前面没有空格和逗号的实数【英文标题】:java Regex: how to find real number not preceded by spaces and comma 【发布时间】:2020-08-25 11:09:22 【问题描述】:

我有以下一段文字:

"M -0.6,-0.5 V 256e-17 512.5 h 44.107422 c 20.577609,0 l-3,-4 2,2 -1.9e-12 , 0"

我想让正则表达式检测所有实数除了以逗号开头的数字。我做不到,谁能帮帮我?

我为相反的情况写了正则表达式:

, *[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?

它检测每个以逗号开头的实数。

我正在使用这个表达式进行实数检测:

[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?

我尝试用lookbehind做一些事情,比如:

(?<!, *)[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?

但是“后视组没有明显的最大长度”或向我提供了另一个错误。

我正在考虑两种不同的方式:

    从所有实数中排除以逗号开头的数字,但不知道如何, 查找前面没有逗号的数字,也知道如何。

我正在使用 java.util.regex

谢谢你的问候, 女士们。

【问题讨论】:

欢迎来到***。请不要包含诸如“谢谢你和问候,MSZ”之类的语句。 .请参阅此处了解更多信息:meta.stackexchange.com/questions/2950/… 您可能应该为此使用捕获组。然后你可以做类似 [^\,](real_number) 的事情,并获取捕获组的内容 【参考方案1】:

您可以使用像您这样的正则表达式,但将后向转换为可选的捕获组:

(, *)?([-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?)

见its demo。一旦你得到匹配,丢弃所有匹配第 1 组的那些。

见Java demo:

String s = "M -0.6,-0.5 V 256e-17 512.5 h 44.107422 c 20.577609,0 l-3,-4 2,2 -1.9e-12 , 0";
Matcher m = Pattern.compile("(, *)?([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?)").matcher(s);
List<String> results = new ArrayList<>();
while (m.find()) 
    if (m.group(1) == null) 
        results.add(m.group(2));
    

System.out.println(results);

输出:

[-0.6, 256e-17, 512.5, 44.107422, 20.577609, -3, 2, -1.9e-12]

【讨论】:

【参考方案2】:

编辑:由于我之前在匹配后不需要任何处理的正则表达式在逗号后面有空格时不起作用(sigh),所以这里有一个不同的不应该采取太多步骤的解决方案。

Link to new regex

首先使用正则表达式((?&lt;!([,\-+.0-9]))(?&lt;![0-9][eE])(?&lt;!, ))(\s*[-+]?+)((\d*\.\d+)|\d+)([eE][-+]?\d+)?。这将匹配实数,但也包括数字前的空格。

然后,要删除空格,您可以这样做

Pattern
  .compile("((?<!([,\-+.0-9]))(?<![0-9][eE])(?<!, ))(\s*[-+]?+)((\\d*\\.\\d+)|\\d+)([eE][-+]?\\d+)?")
  .splitAsStream(inputYouWantToMatch)
  //You could also use regex like "^ *" to trim it, if you wish
  .map(str -> (str.startsWith(" ")) ? str.replaceFirst(" *", "") : str)
  .collect(Collectors.toList()) //or whatever you prefer to collect it


Wiktor Stribizew 的另一个答案很棒,但这实际上不需要以后进行任何处理,并且(可能)也可以正常工作。

((?&lt;!([,\-+.0-9]))(?&lt;![0-9][eE]))[-+]?((\d*\.\d+)|\d+)([eE][-+]?[0-9]+)?.

如果你想让它匹配以2. 之类的点结尾的数字,那么你可以使用这个:

((?&lt;!([,\-+.0-9]))(?&lt;![0-9.][eE]))[-+]?((\d*\.\d+)|\d+\.?)([eE][-+]?[0-9]+)?

Link to online regex tester for the first one(感谢链接,Wiktor Stribizew)

这是一个实数的正则表达式,但它之前不能有这些东西

逗号(因为你说过) 加号或减号(所以它与,-2 中的2 不匹配 一个数字,然后是“e”(因此它与 ,2e17 中的 17 不匹配) 其他数字(因此它与 ,23 中的 3 不匹配)

此外,在可选的加号或减号和“e”部分之间,它必须有多个数字 (\d+) 或(零个或多个数字后跟一个句点后跟一个或多个数字)使其与空输入不匹配(请原谅我没有正确使用括号,否则那些“或”会令人困惑。

【讨论】:

这是一个非常好的正则表达式,但是.. 当我们考虑以下字符串时: M 10,10 20, 20 ,逗号和第二个数字之间有一个空格。因此,正则表达式捕获最后一个数字,它不应该。添加另一个简单的lookbehind解决了一个空格的问题:link,但是有没有办法让正则表达式不检测数字,如果它和逗号之间是多个空格字符?我们不能像那样做lookbehind (? @MSZ 我创建了一个新的正则表达式,但之后需要在比赛开始时修剪空格。希望对你有帮助【参考方案3】:

实际上决定这样做。完美运行。

// Parsing points. X'es are detected, when ',' is after number
matcher = Pattern.compile("(, *)?([-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?)").matcher(commandList.get(y));
ArrayList<Double> xPointsList = new ArrayList<Double>();
ArrayList<Double> yPointsList = new ArrayList<Double>();
// If it's y number, matcher.group(0) looks like this ", 123", Double.valueOf() throws an exception and number is read properly with matcher.group(2)
while(matcher.find()) 
    double number = 0;
    try 
        number = Double.valueOf(matcher.group(0));
        xPointsList.add(number);
     
    catch(Exception e) 
        number = Double.valueOf(matcher.group(2));
        yPointsList.add(number);
    

【讨论】:

以上是关于java Regex:如何找到前面没有空格和逗号的实数的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式 - 匹配第二个逗号(或逗号和空格)之后的所有内容

php如何截取逗号之前的字符

Java Regex - 拆分逗号分隔列表但排除方括号内的逗号

java怎么以空格,英文逗号和句号拆分一个字符串,一个逗号我会,同时三个该怎么写

如何删除数组中的最后一个逗号和空格? Java [重复]

Java如何清除空格?