我正在写一个正则表达式(如果这很重要的话,在Java中使用),它试图匹配$后面的数字(可以是浮点数)(允许$和数字之间有空格),但前提是它前面的单词不是单词'LOST'。
如果有多个可能的匹配项,则应返回第一个数字。
为简单起见,假设所有字符都是大写。
例如,在下面的句子中:“I PAID $10.12 FOR THE BEER”,10.12将匹配。对于句子“I LOST $11.34 IN THE GAME”,将不会有匹配。对于“我在游戏中输掉了11.34美元,但为啤酒支付了10.12美元”,仍然匹配10.12美元。
我得到的正则表达式是
.*?(?<!LOST )[$]\s*(?<NUMBER>[0-9]*[.]?[0-9]*).*
我的正则表达式通常工作得很好,尽管我想知道是否有更简单的方法来编写它/如果我错过了任何角落的情况。一个小问题是,如果LOST和$之间有一个以上的空格,我仍然不想匹配,但目前我的正则表达式将匹配。不幸的是,负向后看必须具有固定的宽度。
说明:为了澄清,当我说“紧接在它前面的单词不是单词'LOST'”时,我的意思是在'$'之前不能有'LOST\s'。这意味着'LOST $123'和'LOST $123'都不应该匹配123,而是'LOST!123美元“可以匹配123。理由是货币不应该被LOST直接“作用”;如果在LOST和$之间有除\s以外的任何东西,那么LOST很有可能不会直接“作用于”该货币。
4条答案
按热度按时间jyztefdp1#
假设
"LOST"
和美元符号之间可能有1到99个空格。我还假设这个数字有两位小数,并且没有逗号作为千位分隔符。然后可以尝试将字符串与正则表达式进行匹配如果存在匹配项,则名为
NUMBER
的捕获组将包含感兴趣的美元金额。Demo
将光标悬停在链接处的正则表达式上,以获取表达式中每个元素的说明。
另一种方法是尝试匹配正则表达式
Demo
在这种情况下,不要注意没有捕获的匹配;只发送给接收到的,在这种情况下,捕获组
NUMBER
将包含感兴趣的货币值。这里匹配,但不捕获,值前面是“LOST”,后面是一个或多个空格,后面是美元符号。有人可能会说它吞噬了这样的子串。
qv7cva1a2#
受blhsing's answer的启发,我提出了这个正则表达式,它可能看起来更干净,并且具有更广泛的边缘情况覆盖:
因为Java不能有非固定宽度的lookbehind。你向后看的位置很关键。
1.由于您不希望货币为
LOST
之前的单词,因此可以先匹配单词边界:1.然后,您需要确保该字不是
LOST
1.之后,将您的货币匹配放在它后面,前面是可选的非单词字符:
1.然后,添加一些边缘情况,例如以货币开头的字符串:
查看test cases
vof42yt13#
由于Java中的lookbehind模式必须具有固定的宽度,因此可以通过使用负lookahead模式来排除单词
LOST
,从而允许可变数量的空格。还包括交替模式中的^
行的开头,以防在那里发生匹配:演示:https://regex101.com/r/4pqyc0/7
olqngx594#
我不会在这里使用lookbehind,而是一个捕获组: