Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何匹配不在两个特殊字符之间的正则表达式?_Ruby_Regex - Fatal编程技术网

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

Ruby 如何匹配不在两个特殊字符之间的正则表达式?,ruby,regex,Ruby,Regex,我有这样一个字符串: a b c a b“a b”b a“a” 如何匹配不是由“分隔的字符串的一部分的每个a?我想匹配此处粗体的所有内容: abcab“ab”baa 我想替换那些匹配项(或者更确切地说,通过用空字符串替换它们来删除它们),因此删除用于匹配的引用部分将不起作用,因为我希望这些部分保留在字符串中。我使用的是Ruby。针对正则表达式爱好者的完整正则表达式解决方案,而不考虑性能或代码可读性 此解决方案假定不存在转义语法(使用转义语法,“sbd\”a“中的a被计为字符串内部) 伪代码: p

我有这样一个字符串:

a b c a b“a b”b a“a”

如何匹配不是由
分隔的字符串的一部分的每个
a
?我想匹配此处粗体的所有内容:

abcab“ab”baa


我想替换那些匹配项(或者更确切地说,通过用空字符串替换它们来删除它们),因此删除用于匹配的引用部分将不起作用,因为我希望这些部分保留在字符串中。我使用的是Ruby。

针对正则表达式爱好者的完整正则表达式解决方案,而不考虑性能或代码可读性

此解决方案假定不存在转义语法(使用转义语法,
“sbd\”a“
中的
a
被计为字符串内部)

伪代码:

processedString = 
    inputString.replaceAll("\\".*?\\"","") // Remove all quoted strings
               .replaceFirst("\\".*", "") // Consider text after lonely quote as inside quote
然后可以在
processedString
中匹配所需的文本。您可以删除第二替换,如果你认为文本后,单独报价作为外部报价。 编辑

在Ruby中,上面代码中的正则表达式是

/\".*?\"/
gsub一起使用

sub一起使用


为了解决更换问题,我不确定这是否可行,但值得一试:

  • 申报柜台
  • 将regex
    /(\“| a)/
    与gsub和supply函数一起使用
  • 在函数中,如果匹配为
    ,则递增计数器,并返回
    作为替换(基本上没有更改)。如果匹配为
    a
    则检查计数器是否为偶数:如果偶数,则提供替换字符串;否则,仅提供匹配的内容

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

result = subject.gsub(/a(?=(?:[^"]*"[^"]*")*[^"]*\Z)/, '')
当且仅当匹配的
a
前面有偶数个引号时,这将用空字符串替换所有
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
如果可以在引号中使用转义引号(
a“length:2\”
),则仍然可以使用转义引号,但会更加复杂:

result = subject.gsub(/a(?=(?:(?:\\.|[^"\\])*"(?:\\.|[^"\\])*")*(?:\\.|[^"\\])*\Z)/, '')
这本质上与上面的正则表达式相同,只是将
(?:\\.\124;[^“\\])
替换为
[^]


js编码器,复活这个古老的问题,因为它有一个简单的解决方案,没有提到。(在为某个客户进行研究时发现了您的问题。)

正如您可以看到的,与公认答案中的正则表达式相比,正则表达式非常小:
(“[^”]*”)| a

看到这个了吗

参考


正则表达式一次匹配一个子字符串。如何循环正则表达式是托管语言的一项功能。您使用的是哪种语言?这与OP要求中提到的“A”有关吗?@ElRonnoco:是的。我不是一次完成所有操作,而是删除所有带引号的字符串,并在
processedString
。然后搜索文本会很容易。不过,我的解决方案有一个假设。我的问题是,我想先匹配它们,然后再替换它们。但我希望引用的部分保留在字符串中。您正在删除引用的部分,然后匹配所有
a
对吗?我认为Ruby没有
g
标志。@dotweb:另一个解决方案是用特殊字符替换
,您可以确定该字符不会出现在输入字符串中,但这是一个非常粗糙的解决方案,我不推荐使用它。意外地,它被选中了。这个答案是不正确的,因为它也将完全匹配引用的部分,而不是只匹配字符串外的“a”字符。被接受的答案按预期工作。
result = subject.gsub(/a(?=(?:(?:\\.|[^"\\])*"(?:\\.|[^"\\])*")*(?:\\.|[^"\\])*\Z)/, '')
(?:     # Match either...
 \\.    # an escaped character
|       # or
 [^"\\] # any character except backslash or quote
)       # End of alternation
subject = 'a b c a b " a b " b a " a "'
regex = /("[^"]*")|a/
replaced = subject.gsub(regex) {|m|$1}
puts replaced