我对regex非常缺乏经验,所以请耐心等待。我的程序检查用户输入中的测量单位,并将其从公制转换为英制,反之亦然。以下是我的案例陈述片段:
when /ltr|ltrs|liter|liters|litre|litres/
puts "#{int} liter(s) is equal to #{calc(int, 3.78541)} gallon(s), #{rem(int, 3.78541, 4)} quart(s)!"
when /gal|gals|gallon|gallons/
puts "#{int} gallon(s) is equal to #{calc(int, 0.264172)} liter(s), #{rem(int, 0.264172, 1000)} milliliter(s)!"
我想将第一个when
更改为也包括/l/
。为了防止它与其他when
条件(如gallon
(中存在的l
混合,我想使用类似/blb/
的东西。问题是,这使得程序无法识别l
,如果它与数字相邻,例如在20L
中。有没有一种方法可以创建一个忽略相邻数字的单词边界?
因为左边的单词边界也可以写成(?<!w)
,右边的边界可以写成(?!w)
,所以你只需要从中减去一个d
。
你可以使用
(?<![^Wd])L(?![^Wd])
或与字符类交集:
(?<![w&&[^d]])L(?![w&&[^d]])
整个正则表达式看起来像/(?<![^Wd])(?:<your_regex>)(?![^Wd])/i
:
/(?<![^Wd])l(?:trs?|it(?:er|re)s?)?(?![^Wd])/i
/(?<![w&&[^d]])l(?:trs?|it(?:er|re)s?)?(?![w&&[^d]])/i
请参阅regex演示#1和regex演示#2。
详细信息
(?<![^Wd])
/(?<![w&&[^d]])
-在此之前,不能有非单词或数字字符以外的字符(排除了d
的前导词边界(l
-一个l
字母(?:trs?|it(?:er|re)s?)?
-可选序列:trs?
-tr
或trs
|
-或it(?:er|re)s?
-it
,然后是er
或re
,然后是可选的s
(?![^Wd])
/(?![w&&[^d]])
-紧接着,不能有非单词或数字字符以外的字符(不包括d
的尾随单词边界(
i
标志将使正则表达式不区分大小写。
(?<=d|b)L(?=d|b)
您可以使用正向查找来断言L的正旁边是单词边界或数字。
(?<=d|b)
断言在模式的正前方有一个数字或单词边界L
匹配一个L
(?=d|b)
断言直接在模式之后,有一个数字或单词边界
通过使用查找,您可以在不匹配的情况下断言某个数字的存在。这使您可以验证数字的存在,而无需在正则表达式中实际使用它们。
演示