【问题标题】:Regex to find lines containing numbers, starting with text, but removing text from the ocurrence正则表达式查找包含数字的行,以文本开头,但从出现中删除文本
【发布时间】:2019-12-09 14:05:30
【问题描述】:

有以下输入:

Testing 42702434884 
Testing 064352729-13
05.994.401/0001-53
Testing 134.632.125-03

我正在尝试获取包含数字的行,只考虑以文本开头的行,并从结果中删除文本,

目前我尝试了以下表达式:

(?!a-zA-Z)\b(\d{11}|\d{14})|(\d{3}\.\d{3}\.\d{3}\-\d{2}|\d{3}\d{3}\d{3}\-\d{2})|(\d{2}\.\d{3}.\d{3}\/\d{4}-\d{2}|\d{2}\d{3}\d{3}\d{4}-\d{2})\b

我能够从结果中删除文本,并找到包含模式的行,但不能只过滤以文本开头的行。以Here is the result为例

如何在从结果中删除文本的同时过滤以文本开头的行?

【问题讨论】:

  • 来自regex tag info:“由于正则表达式尚未完全标准化,所有带有此标签的问题还应包含一个指定适用的编程语言或工具的标签。”
  • 你是这个意思吗? ^[a-zA-Z]+ (?:(?:\d{11}|\d{14})|(?:\d{3}\.\d{3}\.\d{3}\-\d{2}|\d{3}\d{3}\d{3}\-\d{2})|(?:\d{2}\.\d{3}.\d{3}\/\d{4}-\d{2}|\d{2}\d{3}\d{3}\d{4}-\d{2})\b)regex101.com/r/wVfvSw/1
  • @nullptr 如果您愿意,可以将第一部分设为可选regex101.com/r/d5xVYA/1

标签: java regex regex-lookarounds regex-group


【解决方案1】:

对您尝试的模式使用负前瞻(?!a-zA-Z)\b 总是正确的,因为后面是一个数字,因此可以省略。

您可以使用锚点 ^ 来断言字符串的开头,并匹配 1 次以上的字符 a-zA-Z 后跟一个空格,而不是使用否定的前瞻 (?!a-zA-Z),并将其设为可选 (?:[a-zA-Z]+ )?如果你想匹配所有的例子

在所有交替周围附加一个组。

如果您不需要所有捕获组,则可以将它们设为不捕获 (?:,但要保留的数字除外。

这些值在第 1 组中。

^(?:[a-zA-Z]+ )?((?:\d{11}|\d{14})|(?:\d{3}\.\d{3}\.\d{3}\-\d{2}|\d{3}\d{3}\d{3}\-\d{2})|(?:\d{2}\.\d{3}.\d{3}\/\d{4}-\d{2}|\d{2}\d{3}\d{3}\d{4}-\d{2})\b)

注意 Java 对反斜杠进行双重转义。

Regex demo | Java demo


要只获得 3 个匹配项,您可以使用

^[a-zA-Z]+ ((?:\d{11}|\d{14})|(?:\d{3}\.\d{3}\.\d{3}\-\d{2}|\d{3}\d{3}\d{3}\-\d{2})|(?:\d{2}\.\d{3}.\d{3}\/\d{4}-\d{2}|\d{2}\d{3}\d{3}\d{4}-\d{2})\b)

Regex demo | Java demo

【讨论】:

  • 感谢您的帮助!这将排除不以文本开头的行,但不会从最终结果中删除文本,例如我现在得到Testing 42702434884 作为最终结果,有没有办法只检索42702434884?
  • 检查了你的 Java 示例,只有一个我无法执行的调整,05.994.401/0001-53 不应该出现,因为它不是以文本(不是数字)开头
  • @nullptr 这是我在第一个答案中的示例模式。 ^[a-zA-Z]+ ((?:\d{11}|\d{14})|(?:\d{3}\.\d{3}\.\d{3}\-\d{2}|\d{3}\d{3}\d{3}\-\d{2})|(?:\d{2}\.\d{3}.\d{3}\/\d{4}-\d{2}|\d{2}\d{3}\d{3}\d{4}-\d{2})\b) 见 regex101.com/r/CMufdu/1 见这个 Java 演示 ideone.com/CrdREv
  • 明白了!谢谢!
【解决方案2】:

不清楚您希望如何解析这些数字。这对你有用吗?

  1. 首先它只过滤以文本开头的行。
  2. 然后它会删除直到第一位数字的所有字符。
  3. 并将它们存储在一个数组中。
      String[] lines = {
            "Testing 42702434884", "Testing 064352729-13", "05.994.401/0001-53",
            "Testing 134.632.125-03"
      };

      String[] filtered =
            Arrays.stream(lines).filter(k -> k.matches("^\\D+.*")).map(
                  s -> s.replaceAll("(^\\D+)", "")).toArray(String[]::new);

      for (String s : filtered) {
         System.out.println(s);
      }

以上印刷品


42702434884
064352729-13
134.632.125-03

【讨论】:

    猜你喜欢
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多