我有一個這樣的字符串:如何匹配不是兩個特殊字符之間的正則表達式?
A B C A B 「A B」 B一 「一」
如何匹配每一個a
不是由"
分隔字符串的一部分?我想匹配的一切,這是大膽的在這裏:
一個 BC 一個 B 「AB」 B 一個 「一」
我想,以取代那些比賽(或者更確切地說,刪除他們通過替換爲空字符串),所以刪除引用的部分匹配將無法正常工作,因爲我希望那些留在字符串中。我正在使用Ruby。
我有一個這樣的字符串:如何匹配不是兩個特殊字符之間的正則表達式?
A B C A B 「A B」 B一 「一」
如何匹配每一個a
不是由"
分隔字符串的一部分?我想匹配的一切,這是大膽的在這裏:
一個 BC 一個 B 「AB」 B 一個 「一」
我想,以取代那些比賽(或者更確切地說,刪除他們通過替換爲空字符串),所以刪除引用的部分匹配將無法正常工作,因爲我希望那些留在字符串中。我正在使用Ruby。
假設引號是正確的平衡,也沒有逃脫引號,那麼它很簡單:
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
+1這是答案 – 2012-07-16 12:33:23
哇,令人印象深刻的正則表達式!我花了一段時間,但現在我明白它是如何工作的。:)爲什麼downvote? – 2012-07-16 12:55:07
針對正則表達式愛好者的全面的正則表達式解決方案,而不關心性能或代碼可讀性。
該解決方案假定沒有轉義語法(轉義語法,"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
檢查計數器是否均勻:如果連供應替換字符串;否則,只需提供任何匹配的東西。這與OP要求中提到的'a's有什麼關係? – 2012-07-16 11:24:36
@ElRonnoco:是的。我不是一次做所有事情,而是刪除所有引用的字符串,並且只在'processedString'中保留未加引號的部分。然後搜索文本將很容易。雖然我的解決方案有假設。 – nhahtdh 2012-07-16 11:26:24
啊,這個想法是*然後*你做'a's的替換...... – 2012-07-16 11:27:31
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
參考
正則表達式一次只匹配一個子字符串。如何循環正則表達式是託管語言的一個特性。你使用哪種語言? – tripleee 2012-07-16 11:15:10
@tripleee Ruby。 – 2012-07-16 11:16:08