1

私の友人は、私が使用している正規表現が長すぎる場合、おそらくその仕事には不適切なツールだと言いました。このテキストを解析するためのより良い方法について何か考えはありますか? すべてを配列に返す正規表現がありますが、簡単にチャンクアウトできますが、別のより簡単な方法があれば、それを見たいと思います。

外観は次のとおりです。

 2 AB 123A 01JAN M ABCDEF AA1   100A  200A  02JAN T /ABCD /E    

その内訳は次のとおりです。

  • 2は行番号で、これらの範囲は から1まで99です。書式設定のために表示できない場合は、10 未満の数字の先頭にスペース文字があります。

    スペースは、*

  • ABデータの重要な単位 (UOD) です。

    AB/CD別の重要な UOD であるが先頭に追加される場合があります。

  • 123重要な UOD です。1(先頭に 4 つのスペースを追加)から99999.

  • A重要な UOD です。

  • 01JAN日/月の組み合わせなので、両方の UOD を抽出する必要があります。

  • M曜日名の短縮形です。これは ~ の間の数値である可能性が1あり7ます。

  • ABC重要な UOD です。

  • DEF重要な UOD です。

    後のスペースDEF*

  • AA10 文字の場合もあれば、5 文字の場合もあります。重要ではありません。

  • 100Aはタイムスタンプですが、形式は1300. 時刻は、時刻または午後の時刻のA場合があります。N1200P

  • 次に、別のタイムスタンプが表示されます。

  • 次の日付部分が存在しない可能性があります。たとえば、これは有効です。

    93*DE/QQ51234 30APR J QWERTY*QQ0   1250   0520 /ABCD*ASDFAS /E             
    
  • 表示されるデータ/ABCD*ASDFAS /Eはアプリケーションとは関係ありませんが、ここに 2 番目の日付スタンプが表示される場合があります。フロントスラッシュは別のもの (文字など) の場合があります。

注:
スペースで区切られていません。体の一部が他の部分にぶつかっています。文字位置は、リストの最初の 2 つまたは 3 つの項目についてのみ正確です

何も省略したとは思いませんが、正規表現を書くよりもこのような文字列を解析する簡単な方法があれば教えてください。

4

4 に答える 4

6

これは、正規表現に最適なタスクです。テキストにはネストが含まれておらず、一致するアイテムは個別に取得されたかなり単純なものです。

ほとんどの正規表現構文には、x空白とコメントを読みやすくする傾向のあるフラグまたはモードがあります。例えば:

$regex = '@
    # 2 is the line number, these range from 1 all the way to 99.
    # There is a space character prepending numbers less than 10.
    # The space may or may not be replaced by an *.
    [ *]\d|\d\d
    \s

    # AB is an important unit of data (UOD).
    # AB may be prepended by /CD which is another important UOD.
    (/CD)?AB
    \s

    # 123 is an important UOD. It can range from 1 (prepended by 4 spaces)
    # to 99999.
    \s{4}\d{1}|\s{3}\d{2}|\s{2}\d{3}|\s{1}\d{4}|\d{5}
@x';

等々。

于 2011-04-15T20:10:27.177 に答える
2

A regex seems fine for this application, but for simplicity and readability, you might want to split this into several regexes (one for each field) so people can more easily follow which part of the regex corresponds to which variable.

于 2011-04-15T20:11:42.317 に答える
1

いつでも手動で独自のパーサーをコーディングできますが、それは正規表現よりも多くのコード行になります。ただし、コードの行は、おそらく読者にとって従うのがより簡単になります。

于 2011-04-15T20:01:00.103 に答える
0

行ごとに処理するカスタム パーサーを作成するだけです。すべてがスペース/カンマ区切りではなく固定位置にあるように見えるので、それらを必要なものへのインデックスとして使用するだけです:

line_number = int(line_text[0:1])
ab_unit = line_text[3:4]
...

実際にスペースで区切られている場合は、単純にsplit()各行を解析してから、各チャンクを必要に応じてコンポーネント パーツに分割します。

于 2011-04-15T20:00:40.260 に答える