2009-08-21 28 views
4
THOSスペースが

正規表現ではなく、「文字列」にスペースをマッチング

Mary had "a little lamb" 

それが一致する必要がありますで、例えば二重引用符( ")。で囲まれていない場合にのみ、私はスペースに一致する正規exressionを探しています

私は二重引用符ではありませんスペースではなく、引用符で文字列を分割する最初のAN第二の空間ではなく、他の人。

私はC++を使用していますQtツールキットを使い、使いたいQString :: split(QRegExp)。 QStringはstd :: stringと非常によく似ていて、QRegExpは基本的にクラスにカプセル化されたPOSIX正規表現です。そのような正規表現が存在する場合、分割は簡単です。

例:

Mary had "a little lamb"  => Mary,had,"a little lamb" 
1" 2 "3      => 1" 2 "3 (no splitting at ") 
abc def="g h i" "j k" = 12 => abc,def="g h i","j k",=,12 

編集のため申し訳ありませんが、私は最初の質問をしたときに、私は非常に不正確でした。今はもう少し明確になることを願っています。

+0

質問はここに回答されています[NOT Rubyで引用符ですべてのスペースを置き換えるために正規表現を使用](http://stackoverflow.com/questions/205521/using-regex-to-replace-all-spaces-not-in -quotes-in-ruby) –

答えて

7

(私はあなただけ同じで、自分自身に答えるほぼ正確に掲示知っているが、私はこのすべてを捨てるに耐えることはできませんが起こらないことを確認するため、長い文字列で、ランタイムをテストします。: - /)

それが正規表現分割操作であなたの問題を解決することができるならMSaltersが言ったように、正規表現は、引用符の偶数と一致する必要があります。しかし、分割正規表現は、分割しているスペースだけに一致する必要があるため、残りの作業は先読みで行う必要があります。ここで私が使用するものです:テキストがうまく形成され

" +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)" 

場合は、引用符の数が偶数のための先読みがちょうどマッチしたスペースが引用されたシーケンス内にないことを決定するのに十分です。つまり、lookbehindsは必要ではありません。これは、QRegExpがそれらをサポートしていないためです。エスケープされた引用符も収容できますが、正規表現はかなり大きくて醜いものになります。しかし、テキストが整形式であるかどうかを確認できない場合は、split()で問題を解決できる可能性は非常に低いです。それがなかった--ifところで

、QRegExpはは、先読みOR lookbehindsをサポートしていないと、POSIX regular expressionsを実装していません。代わりに、Perlと互換性のあるregexフレーバのゆるやかに定義されたカテゴリに分類されます。

+0

さて、私は_basically_ POSIX ;-)を書いた。私はlookbehindsを検索したとき、何かが見つからなかったことに気づいた。しかし、まもなく、私はいつも一対の引用を仮定して、私はそれらを必要としないことに気付きました。おそらくQtでバグを報告するべきでしょう。とにかく、正規表現の改良のための+1。 – hirschhornsalz

+1

「POSIX」という用語をゆるやかに使用していたことがわかりました。私は単に他人がそうでないかもしれないことを指摘していました私はQRegExpを調べて* POSIX標準ではないことを確認しなければなりませんでした(または、具体的には、先読みベースのソリューションを推奨することができます)。 –

4

"a" b "c"はどうなりますか?

部分文字列" b "では、スペースは引用符で囲まれています。

- 編集 -

私はそれが標準引用符(すなわちU + 0022の奇数が先行し、続いている場合はスペースが「引用符の間」であると仮定し、私は「それらの面白いUnicodeを無視します引用符 ")。 ^[^"]*("[^"]*"[^"]*)*"[^"]* [^"]*"[^"]*("[^"]*"[^"]*)*$

("[^"]*"[^"]*)は引用符のペアを表し:あなたは、次の正規表現を必要とする意味

("[^"]*"[^"]*)*は、偶数であり、奇数である("[^"]"[^"]*)*"です。実際に引用された文字列部分の後に別の奇数の引用符が続きます。文字列の先頭からすべての見積もりをカウントする必要があるため、^$のアンカーが必要です。これにより、上記の部分文字列の問題" b "には、部分文字列を一切参照しないで応答します。価格は、入力内のすべての文字を文字列全体と照合する必要があるため、これをO(N * N)分割操作に変換します。

正規表現でこれを行うことができる理由は、必要なメモリが限られているためです。効果的に1ビット。 "これまでに奇数か偶数の引用符を見たことがありますか?"実際には、""個のペアを個別に一致させる必要はありません。

これは唯一の解釈ではありません。ペアにする“funny Unicode quotes”を含める場合は、““double quoted””文字列も処理する必要があります。これは、開かれた回数がであることを意味します。つまり、無限の記憶容量が必要であるということです。これは、もはや通常の言語ではなく、正規表現を使用できないことを意味します。 QED。

とにかく可能だったとしても、適切なパーサーが必要です。各文字の前にある引用符の数を数えるO(N * N)の動作は面白くない。 Str [N]に先行するX引用符があることをすでに知っている場合は、O(N)ではなくStr [N + 1]の前にいくつの引用符があるかを判断するO(1)操作でなければなりません。可能な答えはすべてXまたはX + 1だけです!

+0

これは質問であり、答えではありません。コメントを使用します。 – Gumbo

+0

これは疑問符の答えです;)問題は、彼が問題のために間違ったツール(スタックベースのパーサの代わりに正規表現)を使用していることです。そして、「近くの理由はありません:問題は正規表現で解決できません」 – MSalters

+0

私が尋ねる理由は、パーサの使用を避けたいからです。私は "安い"解決策を望んでいました。正規表現を使用する解決策がない場合、数学的な証明を提供し、私は答えとしてそれを受け入れます:-) 厳密で厳密である必要はありません:-) – hirschhornsalz

-2

最も単純な正規表現の解決法:全体のスペースと引用符を一致させます。後で引用符をフィルタにかける

"[^"]*"|\s 
1

文字列の引用符が単純な場合(例のように)、代替を使用できます。この正規表現は簡単に引用符で囲まれた文字列を探します。スペースを見つけることに失敗しました。 Perlで

/(\"[^\"]*\"| +)/ 

あなたがsplit()を呼び出すときに正規表現でグループ化を使用する場合、この関数は要素だけでなく、(この場合は、私たちの区切り文字)キャプチャグループだけではなくを返します。空白とスペースのみの区切り文字を除外すると、目的の要素リストが得られます。私は、同様の戦略はC++で働くかどうかは知らないが、以下のPerlコードは、作業を行います。

use strict; 
use warnings; 
while (<DATA>){ 
    chomp; 
    my @elements = split /(\"[^\"]*\"| +)/, $_; 
    @elements = grep {length and /[^ ]/} @elements; 
    # Do stuff with @elements 
} 

__DATA__ 
Mary had "a little lamb" 
1" 2 "3 
abc def="g h i" "j k" = 12 
4

MSaltersは、右のトラックに私を押しました。彼が与えた正規表現は常に文字列全体と一致するので、split()には適していないが、これは先読み一致によって部分的に利用されるという答えに伴う問題。引用符が常にペアになっている(実際には)と仮定すると、私はすべてのスペースに分割することができますの後に偶数の引用符が続きます。 Cなし

正規表現をエスケープし、単一引用符でソースで

' (?=[^"]*("[^"]*"[^"]*)*$)' 

のように見えるそれがようやくえっ、シンプル

QString buf("Mary had \"a little lamb\""); // string we want to split 
QStringList splitted = buf.split(QRegExp(" (?=[^\"]*(\"[^\"]*\"[^\"]*)*$)")); 

(QtとC++を使用して)のように見えましたか?パフォーマンスのために

は、文字列はプログラムの開始時に一度解析され、彼らは数十であり、彼らは百文字以内です。私は何も悪いが;-)

関連する問題