【问题标题】:How do I match non-letters before my token?如何在我的令牌之前匹配非字母?
【发布时间】:2018-06-10 06:03:45
【问题描述】:

我使用的是 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


    【解决方案1】:

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

    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" 匹配)。

    【讨论】:

      【解决方案2】:

      似乎 p 之前的反斜杠由于双引号而丢失。

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

      【讨论】:

      • r = Regexp.new("(^|[^\\p{L}]+)#{Regexp.union(GENDER_TOKENS)}") #=&gt; /(^|[^\p{L}]+)(?-mix:m|male|men|f|w|female|wom)/ 修复了您发现的问题,但仍然存在缺陷(例如,"2 freaky 3".match?(r) #=&gt; true)。
      • @CarySwoveland,我同意你的回答,
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多