How to match something with regex that is not between two special characters?

后端 未结 3 1277
梦谈多话
梦谈多话 2020-12-03 11:14

I have a string like this:

a b c a b \" a b \" b a \" a \"

How do I match every a that is not part of a string deli

3条回答
  •  没有蜡笔的小新
    2020-12-03 12:14

    Assuming the quotes are correctly balanced and there are no escaped quotes, then it's easy:

    result = subject.gsub(/a(?=(?:[^"]*"[^"]*")*[^"]*\Z)/, '')
    

    This replaces all the as with the empty string if and only if there is an even number of quotes ahead of the matched a.

    Explanation:

    a        # Match a
    (?=      # only if it's followed by...
     (?:     # ...the following:
      [^"]*" #  any number of non-quotes, followed by one quote
      [^"]*" #  the same again, ensuring an even number
     )*      # any number of times (0, 2, 4 etc. quotes)
     [^"]*   # followed by only non-quotes until
     \Z      # the end of the string.
    )        # End of lookahead assertion
    

    If you can have escaped quotes within quotes (a "length: 2\""), it's still possible but will be more complicated:

    result = subject.gsub(/a(?=(?:(?:\\.|[^"\\])*"(?:\\.|[^"\\])*")*(?:\\.|[^"\\])*\Z)/, '')
    

    This is in essence the same regex as above, only substituting (?:\\.|[^"\\]) for [^"]:

    (?:     # Match either...
     \\.    # an escaped character
    |       # or
     [^"\\] # any character except backslash or quote
    )       # End of alternation
    

提交回复
热议问题