0

使用积极的向后看,各个正则表达式匹配它们各自的字符串。结合起来,它们不会。当通过删除积极的后视来更改它时,它匹配。我不明白为什么并且想知道以便我可以修复它,因为我不希望比赛被取消。

value = /  # match a digit or something wrapped in quotes
        (?<value>
          \d+         # Match a digit
            |         # or
          (?:         # Match something wrapped in double quotes
            (?<=")  # <- this is the point of contention
            [^"]+     # captures anything not a "   
            (?=")
          )
            |         # or
          (?:         # Match something wrapped in single quotes
            (?<=')  # <- or this one
            [^']+     # captures anything not a '
            (?=')
          )
        )
      /x

value.match %q!'filename.rb'!
# => #<MatchData "filename.rb" value:"filename.rb">
value.match %q!"filename.rb"!
# => #<MatchData "filename.rb" value:"filename.rb">
value.match %q!66!
# => #<MatchData "66" value:"66">

所以它匹配任何数字或任何包含在匹配引号中的东西。

long_option = /
        (?<long_option>
          (?<!
            (?:\-\-no\-)   # don't match --no-long
              |
            (?:\-\-\-)     # don't match ---long
          )
          (?<=\-\-)        # it must begin with --
          (?<key_name>
            [a-zA-Z]\w+    # capture the key name
          )
          \b
          (?!
            \-             # make sure it's not part of a longer key
          )
        )
      /x

long_option.match "--long"
# => #<MatchData "long" long_option:"long" key_name:"long">
long_option.match "---long"
# => nil
long_option.match "--long-"
# => nil
long_option.match "--no-long"
# => nil

这也很好地匹配。

现在结合起来,问题开始了:

/#{long_option} #{value}/.match "--long 'filename.rb'"
# => nil

但是如果value在没有对第一个引号进行肯定的情况下重新定义,它匹配:

value2 = /
        (?<value>
          \d+
            |
          (?:
            "       # <- no positive lookbehind
            [^"]+
            (?=")
          )
            |
          (?:
            '       # <- for single quote too
            [^']+
            (?=')
          )
        )
      /x

/#{long_option} #{value2}/.match "--long 'filename.rb'"
# => #<MatchData
 "long 'filename.rb"
 long_option:"long"
 key_name:"long"
 value:"'filename.rb">

我已经尝试将long_option与更简单的匹配结合起来并且它有效,所以我倾向于认为它不是问题的明显根源,因此我的问题是,例如

/#{long_option} abc/.match "--long abc"
# => #<MatchData "long abc" long_option:"long" key_name:"long">

我已经在脑海中完成了比赛,反复试验,模式略有不同,我真的被卡住了。任何帮助或见解将不胜感激。

Ruby 版本是 1.9。

4

1 回答 1

0

/#{long_option} #{value}/不会像您预期的那样匹配双引号或单引号中的字符串,因为正向后视出现在 的开头value,当它前面的字符是双引号或单引号时,匹配成功。但是在 中/#{long_option} #{value}/,前面的字符value是空格,并且由于空格字符不能同时是双引号或单引号,因此该替代匹配永远不会成功。

于 2013-04-14T15:50:06.580 回答