2012-07-16 89 views
5

我有一个这样的字符串:如何匹配不是两个特殊字符之间的正则表达式?

A B C A B “A B” B一 “一”

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

一个 BC 一个 B “AB” B 一个 “一”

我想,以取代那些比赛(或者更确切地说,删除他们通过替换为空字符串),所以删除引用的部分匹配将无法正常工作,因为我希望那些留在字符串中。我正在使用Ruby。

+0

正则表达式一次只匹配一个子字符串。如何循环正则表达式是托管语言的一个特性。你使用哪种语言? – tripleee 2012-07-16 11:15:10

+0

@tripleee Ruby。 – 2012-07-16 11:16:08

回答

13

假设引号是正确的平衡,也没有逃脱引号,那么它很简单:

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

这将替换所有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 

如果你能逃脱引号(a "length: 2\""),它仍然是可能的,但将更加复杂:

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

这在本质上是相同的正则表达式如上所述,只有(?:\\.|[^"\\])代替[^"]

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

+1这是答案 – 2012-07-16 12:33:23

+0

哇,令人印象深刻的正则表达式!我花了一段时间,但现在我明白它是如何工作的。:)为什么downvote? – 2012-07-16 12:55:07

0

针对正则表达式爱好者的全面的正则表达式解决方案,而不关心性能或代码可读性。

该解决方案假定没有转义语法(转义语法,"sbd\"a"中的a被计为字符串内)。

伪代码:

processedString = 
    inputString.replaceAll("\\".*?\\"","") // Remove all quoted strings 
       .replaceFirst("\\".*", "") // Consider text after lonely quote as inside quote 

然后你就可以与您在processedString所需的文本。如果您将单独报价后的文字视为外部报价,则可以删除第二个替换。

EDIT

在Ruby,在代码中的正则表达式以上将与gsub

/\".*/ 

使用

/\".*?\"/ 

sub


用于解决更换问题,我不知道这是否是可能的,但它实在值得尝试:

  • 声明一个计数器
  • 使用正则表达式/(\"|a)/与GSUB,和供应功能。
  • 在函数中,如果匹配为",则增加计数器,并返回"作为替换(基本上没有变化)。如果匹配是a检查计数器是否均匀:如果连供应替换字符串;否则,只需提供任何匹配的东西。
+0

这与OP要求中提到的'a's有什么关系? – 2012-07-16 11:24:36

+0

@ElRonnoco:是的。我不是一次做所有事情,而是删除所有引用的字符串,并且只在'processedString'中保留未加引号的部分。然后搜索文本将很容易。虽然我的解决方案有假设。 – nhahtdh 2012-07-16 11:26:24

+0

啊,这个想法是*然后*你做'a's的替换...... – 2012-07-16 11:27:31

4

js-coder,复活这个古老的问题,因为它有一个简单的解决方案,没有提到。 (发现你的问题而做一些研究的regex bounty quest。)

正如你可以看到在接受答案的正则表达式相比,正则表达式是真的很小:("[^"]*")|a

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

看到这个live demo

参考

How to match pattern except in situations s1, s2, s3

How to match a pattern unless...

相关问题