Ruby 如何匹配不在两个特殊字符之间的正则表达式?
我有这样一个字符串: a b c a b“a b”b a“a” 如何匹配不是由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
?我想匹配此处粗体的所有内容:
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