【问题标题】:Regex numbers from string字符串中的正则表达式数字
【发布时间】:2016-04-10 18:16:46
【问题描述】:

我正在尝试编写一个只能从给定字符串中找到数字的正则表达式。我的意思是:

输入:My number is +12 345 678. I have galaxy s3, its symbol 34abc.

输出:345678(但不是 +123 来自单词 s334 来自 34abc

我只尝试了数字 (\d+) 并与白色和文字字符组合。最接近的是^\d$ 但这不起作用,因为我的数字是较大字符串的一部分,而不是整个字符串本身。能给我一个提示吗?

------- 编辑

看起来我只是不知道如何检查一个字符而不实际将它变成结果。就像“空格字符后面的数字(没有这个空格)”。

【问题讨论】:

  • 你可以合并"\\s",这是任何空白字符
  • 您认为哪些字符是分隔符(即可能围绕数字的字符)?从您的示例中,很明显空格和点是分隔符,而“加号”不是。其他字符呢:减号、逗号、下划线等?
  • 我不知道如何使用它,这样它就会成为模式但不会成为输出的一部分(空格字符后面的数字但没有它)
  • Alex,一开始只能是空格。那我再想点别的。
  • 根据您的定义,678 不适合匹配项,因为它后面跟着一个 . 点。

标签: regex


【解决方案1】:

一般情况下,可以使用lookbehind and lookahead

(?<=^|\s)\d+(?=$|\s)

进入捕获输出的部分是\d+。 Lookbehind 和lookahead 不包括在匹配中。

我只是在正则表达式中包含了空格作为分隔符,但您可以根据您的要求将\s 替换为任何字符类。例如,要允许点作为分隔符(在数字前面和后面),请使用以下正则表达式:

(?<=^|[\s.])\d+(?=$|[\s.])

(?&lt;=^|\s) 应如下所示:

  • (?&lt;= ... ) 定义 lookbehind 组。
  • 必须在\d+ 之前的表达式是^|\s,意思是“行首 (^) 或空格”。

同样,(?=$|\s) 定义了 lookahead 组(它必须跟在捕获的数字之后),它可以是行尾 ($) 或空格。


其他答案中提到的\b 上的注释:这是一个不错的功能,意思是“单词边界”,但“单词字符”不可自定义。这意味着,例如,“+”字符被视为分隔符,如果您使用\b,则无法更改它。通过环视,您可以根据需要自定义分隔符。

【讨论】:

  • 匹配 678,因为它后面跟着一个句点,这就是为什么 my answer 扩展了前瞻以允许标点符号。
  • @Andreas,是的,我在答案中提到了这一点。我正在关注 OP 对问题的评论:at the beginnig it can be only spaces. Then I will think about something more.
【解决方案2】:

您似乎想要的是一个数字序列 (\d+),前面有一个空格 (\s) 或字符串的开头 (^),后跟一个空格或标点符号 ( [\s.,:;!?]) 或字符串结尾 ($),但前面/后面的空格或标点字符不应包含在匹配中,因此您需要正向前瞻 ((?=xxx)) 和后向 ((?&lt;=xxx)) .

(?<=^|\s)\d+(?=[\s.,:;!?]|$)

regex101 for demo

记得在 Java 文字中使用双反斜杠。

【讨论】:

    【解决方案3】:

    更安全的正则表达式

    试试这个:

    (?<=\s|^)\d+(?=\s|\b)
    

    Live Demo on Regex101

    它是如何工作的:

    (?<=\s|^)          # Start of String OR Whitespace (will not select +)
                       # Positive Lookbehind ensures the data is not included in the match
    \d+                # Digit(s)
    (?=\s|\b)          # Whitespace OR Word Boundary
                       # Positive Lookahead ensures the data is not included in the match
    

    Lookarounds 在匹配中不占用任何字符,因此可以使用它们,因此不需要捕获组。例如:

    # Regex /.*barbaz/
    barbaz          # Matched Data Result: barbaz
    foobarbaz       # Matched Data Result: foobarbaz
    
    # Regex (with Positive Lookahead) /.*bar(?=baz)/
    barbaz          # Matched Data Result: bar
    foobarbaz       # Matched Data Result: foobar
    

    正如您在第二个 RegEx 中看到的那样,baz 永远不会包含在匹配的数据结果中,但它是 RegEx 匹配的字符串所必需的。上面的 RegEx 的工作原理相同


    不安全(旧)正则表达式

    你可以试试这个正则表达式:

    \b\d+\b
    

    \b 是一个字边界。但是,这将从+12 中选择12

    您可以将 RegEx 更改为此以阻止 12 被选中:

    (?<!\+)\b\d+\b
    

    这使用 Negative Lookbehind,如果数字前有 +,则会失败。

    Live Demo on Regex101

    【讨论】:

    • 请注意:正则表达式 (?&lt;=\s|^)\d+(?=\s|\b) 将匹配前面有空格和 后跟 *any* 非单词字符的数字, 例如所有这些都将匹配:123+123@123β(β 可以是任何非拉丁字母),但不是 123_。附言我不是反对者。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    相关资源
    最近更新 更多