如何匹配不在两个特殊字符之间的正则表达式?

js-*_*der 11 ruby regex

我有一个像这样的字符串:

abcab"ab"ba"a"

如何匹配每个a不是由分隔的字符串的一部分"?我想匹配这里大胆的一切:

a bc a b"ab"b a "a"

我想替换那些匹配(或者通过用空字符串替换它们来删除它们),因此删除引用的部分以进行匹配将不起作用,因为我希望它们保留在字符串中.我正在使用Ruby.

Tim*_*ker 17

假设引号是正确平衡的并且没有转义引号,那么很容易:

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

a当且仅当匹配前有偶数引号时,这将用空字符串替换所有s a.

说明:

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
Run Code Online (Sandbox Code Playgroud)

如果你可以在引号(a "length: 2\"")中转义引号,它仍然可能但会更复杂:

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

这在本质上是一样的正则表达式如上述,仅代替(?:\\.|[^"\\])[^"]:

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


zx8*_*x81 8

js-coder,复活这个古老的问题,因为它有一个没有提到的简单解决方案.(在为正则表达式赏金任务做一些研究时找到你的问题.)

正如您所看到的,与接受的答案中的正则表达式相比,正则表达式非常小: ("[^"]*")|a

subject = 'a b c a b " a b " b a " a "'
regex = /("[^"]*")|a/
replaced = subject.gsub(regex) {|m|$1}
puts replaced
Run Code Online (Sandbox Code Playgroud)

看到这个现场演示

参考

如何匹配模式除了情况s1,s2,s3

除非......如何匹配模式