如何在令牌之前匹配非字母?

问题描述 投票:2回答:2

我正在使用Ruby 2.4。我对我的RegEx无法正常工作的原因感到非常困惑。我想匹配我的数组中的一个令牌,前提是它不是字母之前的东西。我的阵列是

2.4.0 :023 > GENDER_TOKENS
 => ["m", "male", "men", "f", "w", "female", "wom"]

所以这应该匹配

"2f 25"

应该

"f 100"

但不是

"elf 25"

因为“f”之前的东西不是字母。我以为这会这样做......

2.4.0 :021 > data = "elf 25"
 => "elf 25"
2.4.0 :022 >  Regexp.new("(^|[^\p{L}]+)#{Regexp.union(GENDER_TOKENS)}").match(data.downcase)
 => #<MatchData "elf" 1:"el">

但它的匹配完全相同。为什么不是“^ \ p {L}]”匹配非字母?

arrays ruby regex match
2个回答
2
投票

由于双引号,在p丢失之前似乎是反斜杠。

我不太了解红宝石,但我可以检查here


3
投票

我建议你写下你的正则表达式如下。

r = /(?<!\p{L})#{Regexp.union(GENDER_TOKENS)}(?!\p{L})/
  #=> /(?<!\p{L})(?-mix:m|male|men|f|w|female|wom)(?!\p{L})/

其中写着“不匹配一个字母(负面看后面),匹配一个GENDER_TOKENS的元素,不匹配一个字母(负向前瞻)”。

"2f 25".match?(r)      #=> true
"2f25".match?(r)       #=> true
"2female".match?(r)    #=> true
"male 100".match?(r)   #=> true
"elf 25".match?(r)     #=> false
"2funky 25".match?(r)  #=> false

请注意,需要负向前瞻。如果我们使用正则表达式

rr = /(?<!\p{L})#{Regexp.union(GENDER_TOKENS)}/
  #=> /(?<!\p{L})(?-mix:m|male|men|f|w|female|wom)/

我们可以获得错误的结果,例如

"2funky 25".match?(rr) #=> true

(因为令牌"f"匹配)。

© www.soinside.com 2019 - 2024. All rights reserved.