2012-07-16 8 views
5

が、私はこのような文字列があります:B2つの特殊文字間にない正規表現とのマッチング方法は?

B「B」、C b「を」

がどのように私は"で区切られた文字列の一部ではないすべてのaと一致していますか?

BC B「AB」bの「」

私はそれらのマッチを置き換えたい(というか削除します。私は大胆ここにあるすべてのものを合わせたいですそれらを空の文字列に置き換えることによって)、マッチングのために引用された部分を削除することはできません。なぜなら、それらを文字列に残したいからです。私はRubyを使用しています。

+0

正規表現は、一度に単一のサブストリングと一致します。正規表現をループする方法は、ホスティング言語の機能です。どの言語を使用していますか? – tripleee

+0

@ tripleee Ruby。 OPの要件で述べたように –

答えて

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これは答えです –

+0

うわー、印象的な正規表現!私はしばらくしてきましたが、今はどのように動作するのか理解しています:)なぜdownvoteですか? –

0

パフォーマンスやコードの可読性を気にすることなく、正規表現愛好者のための本格的な正規表現ソリューションです。

このソリューションでは、エスケープ構文がないことを前提としています(エスケープ構文では、"sbd\"a"aは文字列の中に数えられます)。

擬似コード:

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

次にあなたがprocessedStringにしたいテキストを一致させることができます。孤立した見積もりの​​後のテキストを外側の見積もりとみなすと、2番目の置換を削除することができます。 Rubyで

EDIT

、上記のコードでの正規表現は、gsub

/\".*/ 

と共に使用

/\".*?\"/ 

あろう交換用の問題に対処するためにsub


で使用し、私はこれが可能であるかどうかわからないんだけど、それはしようとしてworths:

  • はGSUBで正規表現/(\"|a)/を使用してカウンタ
  • を宣言し、および供給機能。
  • この関数では、一致が"であれば、カウンタをインクリメントし、置換として"を返します(基本的に変更なし)。一致がaの場合、カウンタが偶数であるかどうかを確認します。それ以外の場合は、一致するものを指定してください。引用符を想定し
+0

これはの」とは何かを持っていますか? –

+0

@ElRonnoco:はい。一度にすべてを行うのではなく、引用された文字列をすべて削除し、 'processedString'に引用符で囲まれていない部分だけ残します。その後、テキストを検索するのは簡単です。しかし、私の解決策には前提があります。 – nhahtdh

+0

ああ、あなたは 'a's ... –

4

JS-コーダ、それは言及されなかったシンプルなソリューションを持っていたので、この古代の質問を復活。 (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...

関連する問題