3

次の方法で、文字列を(正規表現を介して)トークンに分割しようとしています。

例 1
入力文字列:'hello'
最初のトークン: '
2 番目のトークン: hello
3 番目のトークン:'

例 2
入力文字列:'hello world'
最初のトークン: '
2 番目のトークン: hello world
3 番目のトークン:'

例 3
入力文字列:hello world
最初のトークン: hello
2 番目のトークン:world

つまり、文字列が単一引用符で囲まれていない場合にのみ文字列を分割し、単一引用符は独自のトークンにする必要があります。

これは私がこれまでに持っているものです:

string pattern = @"'|\s";
Regex RE = new Regex(pattern);
string[] tokens = RE.Split("'hello world'");

これは、例 #1 と例 #3 では機能しますが、例 #2 では機能しません。理論的に正規表現で目的を達成する方法があるかどうか疑問に思っています

4

8 に答える 8

5

各トークンを 1 つずつ消費する単純なレクサーを作成できます。したがって、正規表現のリストがあり、各ポイントでそれらの 1 つと一致しようとします。入力が非常に単純なものではない場合、これが最も簡単でクリーンな方法です。

于 2010-02-09T21:55:30.317 に答える
3

トークン パーサーを使用してトークンに分割します。正規表現を使用して文字列パターンを見つける

于 2010-02-09T21:56:33.450 に答える
2

'[^']+'一重引用符内のテキストと一致します。グループ化する場合は、(')([^']+)('). 一致するものが見つからない場合は、通常の文字列分割を使用してください。1 つの正規表現ですべてを実行しようとするのは意味がないと思います。

編集:質問に対するあなたのコメントから、あなたが示したような単純な入力ではなく、実際にこれをより大きなテキストブロックに適用したいようです。その場合、正規表現はあなたの答えではないと思います。

于 2010-02-09T21:53:15.870 に答える
1

Splitここで使用するのは難しいですが、 a を使用MatchCollectionして、文字列内のすべての一致を見つけることができます。

string str = "hello world, 'HELLO WORLD': we'll be fine.";
MatchCollection matches = Regex.Matches(str, @"(')([^']+)(')|(\w+)");

正規表現は、一重引用符で囲まれた文字列を検索します。見つからない場合は、1 つの単語が必要です。
.net はMatchs のコレクションを返します。各マッチにはいくつかGroupの があります。最初のグループには文字列全体 ( 'hello world') がありますが、残りにはサブマッチ ( 'hello world') があります。また、多くの空の失敗したグループを取得します。
簡単に反復して一致を取得できます。LINQ を使用した例を次に示します。

var tokens = from match in matches.Cast<Match>()
             from g in match.Groups.Cast<Group>().Skip(1)
             where g.Success
             select g.Value;

tokens文字列のコレクションになりました:
hello, world, ', HELLO WORLD, ', we,llbefine

于 2010-02-10T06:10:24.630 に答える
1

最初に引用符で囲まれた文字列で分割してから、さらにトークン化できます。

foreach (String s in Regex.Split(input, @"('[^']+')")) {
    // Check first if s is a quote.
    // If so, split out the quotes.
    // If not, do what you intend to do.
}

(注: Regex.Split がそれらも返すことを確認するには、パターンに括弧が必要です)

于 2010-02-09T22:01:10.893 に答える
1

あなたがやろうとしていることは正確ではありませんが、解決策を探すときに正規表現の条件が役立つ場合があります。

(?<quot>')?(?<words>(?(quot)[^']|\w)+)(?(quot)')

引用符が見つかった場合は、引用符以外が見つかるまで一致します。それ以外の場合は、単語の文字を調べます。結果は、「quot」および「words」という名前のグループに分類されます。

于 2010-02-09T22:04:36.910 に答える
1

と内部のテキストを個別に照合すること'も、テキストのみを照合することもできますが、RegExp では無制限の数の一致は許可されません。または、表現で明示的に指定したオブジェクトのみを一致させることができます。したがって((\w+)+\b)、理論的にはすべての単語を 1 つずつ一致させることができます。外側のグループはテキスト全体に正しく一致し、内側のグループも単語を個別に正しく一致させますが、最後の一致のみを参照できます。

一致した一致のグループを一致させる方法はありません (奇妙な文)。可能な唯一の方法は、文字列を一致させてから、それを別々の単語に分割することです。

于 2010-02-09T22:05:44.833 に答える
0

この正規表現を試してください:

([']*)([a-z]+)([']*)

これは、文字列の最初と最後にある 1 つ以上の一重引用符を見つけます。次に、az セットで 1 つ以上の文字を検索します (大文字と小文字を区別しないように設定しないと、小文字のみが検索されます)。これらをグループ化して、グループ 1 には '、グループ 2 (またはそれ以上) には文字 a - z 以外で分割された単語があり、最後のグループには単一引用符 (存在する場合) があります。

于 2010-02-09T22:02:24.323 に答える