2012-07-16 78 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...

相關問題