4

次のパターンに一致する場合にのみ、Display name大きなテキスト ファイルを解析して抽出する必要があります。area code

  • 行は次で始まりますdisplay name(単語数は任意ですが、数字や特殊文字を含めることはできません)
  • その後に 6 桁の数字が続きます (スペースを含めることができます)
  • 続いて#textタグ

入力ファイル

John doe 123 456 #text some text
Test 123456 #text
Test$test 123456 #text
Test123 345678 #text
Test 123 #test
Test 123456 #test1
Test 123g45 #test

入力と期待される出力

John doe 123 456 #text some text
Display name: John doe
Area code: 123 456

Test 123456 #text
Display name: Test
Area code: 123456

Test$test 123456 #text
Invalid, display name contains special character

Test123 345678 #text
Invalid, display name contains digits

Test 123 #test
Invalid, area code contains only 3 digits

Test 123456 #test1
Invalid, contains invalid tag

Test 123g45 #test
Invalid, area code contains letters

テキスト ファイルを開いて 1 行ずつ読み取る方法は知っていますが、正規表現の記述に問題があります。

これは私が試したことです:

private static void Main(string[] args)
{
    string text = "John Doe 123 45 #text Lorem ipsum dolor :)";
    string pattern = @"(\w+)*([0-9]{2,5}).([0-9]{2,5}).#text";
    Match match = Regex.Match(text, pattern, RegexOptions.IgnoreCase);

    if (match.Success)
    {
        string key = match.Groups[0].Value;
        Console.WriteLine(key);
    }
}

編集:

ここにもう少し説明があります

表示名
表示名には任意の数の単語を含めることができます。たとえば 、 はファースト ネーム、はミドル ネーム、は姓でJohn Michael Smithあるため有効です。は誰かのニックネームであり、英語以外の文字が含まれている可能性があるため、有効な表示名でもあります。ただし、数字を含む名前は無効です。. なんで?これが私たちのビジネス ルールです。数字は使用できません :)ここでは機能すると思いますが、英語以外の文字はカバーされないため機能しません。JohnMichaelSmithŠljakerJohn1\wa-zA-Z

市外局番
ビジネス ルールは単純です。6 つの数字を含める必要があり、形式は問いません。これらはすべて有効な市外局番です: 123456、12 34 56、1234 56 など。正規表現ではスペースを削除する必要はありません。これはコードで処理します。

どんな助けでも大歓迎です!

4

2 に答える 2

0

入力の仕様は、適切な正規表現を記述するにはまだ少しあいまいです。正規表現を記述する前に、仕様を理解するか、少なくとも現在のデータ セットで機能する仮定を立てる必要があります。

これは私が書いた正規表現です。正規表現は行全体を検証します。仮定は後で来る。

^([a-zA-Z ]+)(?<! ) +((?:[0-9] *){6}) *#text( .*)?$

入力にはスペース (ASCII 32) のみを許可します。\sタブやその他の空白文字を許可する場合は、正規表現のスペースを に置き換えることができます。

([a-zA-Z ]+)(?<! ) +: 表示名を照合して取得します。表示名には英字とスペースのみを使用できます。は(?<! )、キャプチャ グループの末尾のスペースを抑制するためにあります。スペースのみの名前を許可しないという別の効果があります。Unicode の任意の文字を一致させたい場合は[\p{L} ]+、代わりに[a-zA-Z ]+.

((?:[0-9] *){6}): 任意の量のスペースで区切られた正確に 6 桁の 10 進数。 +この部分の前に 1 つ以上のスペースが一致するため、表示名に数字を貼り付けることはできません。

 *#text( .*)?: 番号をタグに貼り付けることができます (例: Name 123456#text dfsjhdf); +#text( .*)?これを許可しないように変更します。さらにコメントがある場合、または何も続かない場合( .*)?は、後にスペースがあることを確認します(例: )。#text#textName 123456 #text

この正規表現からキャプチャされたテキストは次のようになります。

  • 表示名: 先頭のスペースとその間のスペースが過剰に含まれる可能性がありますが、末尾のスペースは含まれません。少なくとも 1 つの英語のアルファベット。
  • 市外局番:正確に6 桁の数字です。間に任意のスペースが入る可能性があるため、一致した文字列を処理したい場合があります。
于 2012-12-20T11:40:56.303 に答える
0

正規表現パターンを次のように置き換えることができます。

@"^([\D]+)\s*((?:\d\s*?){6})\s*\#text\s*(.*)$"

これは、順番に検索します

  • 数字以外のシーケンス (グループ 1)
  • 任意の数のスペースが続く
  • 正確に 6 つの数字が続き、それぞれにオプションでスペースが続きます (グループ 2)
  • 任意の数のスペースとリテラル "#text" が続き、オプションでスペースが続きます
  • ラインの残りの部分が続きます (グループ 3)

これは多くの行に対して評価されるため、RegexOptions.Compiledフラグ (つまり: RegexOptions.IgnoreCase | RegexOptions.Compiled) を追加することを検討してください。

表示名は次のように保存されmatch.Groups[1].Valueます。市外局番はmatch.Groups[2].Value、テキストはmatch.Groups[3].Valueです。

于 2012-12-20T12:08:52.690 に答える