正则表达式匹配不跟点(“。”)的数字
Posted
技术标签:
【中文标题】正则表达式匹配不跟点(“。”)的数字【英文标题】:Regex to match a digit not followed by a dot(".") 【发布时间】:2018-01-14 14:07:39 【问题描述】:我有一个字符串
字符串 1(不包括引号)->“我的车号是 #8746253,这真的很酷”
条件 - 数字 8746253,可以是任意长度并且 - 数字也可以紧跟在行尾。
我想分组 8746253 后面不应该有一个点“。” 我试过了,
.*#(\d+)[^.].*
这肯定会得到我的数字,但即使有一个点也会匹配,因为 [.^] 将匹配数字的最后一位数字(例如,3 在以下情况)
字符串 2(不包括引号)->“地球距离 #8746253.Kms,非常远”
我只想匹配 string 1 类型,而不是 string 2 类型。
【问题讨论】:
您需要匹配整行还是只匹配数字?您在模式中有.*
,所以有点不清楚。
整行本身。然后,我只想将数字分组。
好的,我添加了阅读您的问题时想到的所有可能的解决方案。
明显且兼容的修复:#(\d+)(?:[^.\d]|$)
【参考方案1】:
这就像你描述的那样工作
public class MyRegex
public static void main(String[] args)
Pattern patern = Pattern.compile("#(\\d++)[^\\.]");
Matcher matcher1 = patern.matcher("my car number is #8746253 which is actually cool");
if(matcher1.find())
System.out.println(matcher1.group(1));
Matcher matcher2 = patern.matcher("earth is #8746253.Kms away, which is very far");
if(matcher2.find())
System.out.println(matcher1.group(1));
else
System.out.println("No match found");
输出:
> 8746253
> No match found
【讨论】:
【参考方案2】:要匹配#
后面不带点的任意位数,请使用
(?<=#)\d++(?!\.)
++
是一个所有格量词,它将使正则表达式引擎仅在最后一个匹配数字之后检查前瞻 (?!\.)
,并且如果之后有一个点则不会回溯。因此,如果在数字块中的最后一个数字之后有一个嘀嘀,整个匹配将失败。
见regex demo
匹配整行并将数字放入捕获组#1:
.*#(\d++)(?!\.).*
见this regex demo。或者没有前瞻的版本:
^.*#(\d++)(?:[^.\r\n].*)?$
见another demo。在最后一个版本中,数字块后面只能跟一个 可选序列 不是.
的字符,CR 和 LF 后面跟除换行符以外的任何 0+ 字符(@ 987654334@),然后是字符串的结尾 ($
)。
【讨论】:
像往常一样,您的解决方案完美无缺,我有一个问题@Wiktor Stribiżew\d++
为什么要加倍 + 我认为一个就足够了?
@YCF_L:++
是一个 占有 量词,一旦数字后面有一个点,它就会停止正则表达式引擎重试匹配 \d+
模式。当123.
与\d+(?!\.)
匹配时,3
将失败,但正则表达式引擎知道它仍然可以重试\d+
模式以查找不以.
结尾的数字序列,并找到@ 987654344@(因为3
不是.
)。使用++
时,禁止正则引擎以这种方式回溯。
@WiktorStribiżew:我想知道如何实现这个,例如在不支持lookbehinds也不支持这个量词的javascript中?
@eol 您将在否定字符类中使用\d
,就像刚刚显示的@bobblebubble。在我的版本中,^.*#(\d+)(?:[^\d.\r\n].*)?$
。或者只是抓住数字:/#(\d+)(?=[^\d.]|$)/g
进入第 1 组。
@TornikeShavishvili 有两个很棒的网站:regular-expressions.info 和 rexegg.com。一个地方没有关于所有正则表达式风格的完整文档,您需要搜索您感兴趣的每个正则表达式库的官方文档。以上是关于正则表达式匹配不跟点(“。”)的数字的主要内容,如果未能解决你的问题,请参考以下文章