テキストファイルを解析すると、数字の前後にセミコロンが追加されます。数字の前/間に他のすべての単語はハイフンで表示されます。

テキストファイルを解析すると、数字の前後にセミコロンが追加されます。数字の前/間に他のすべての単語はハイフンで表示されます。

次のアカウントを含むテキストファイルがあります。

入力サンプル

Paid 100 15/02/2022 3000
recd 50 15/02/2022 nelur trip 3050
PAID 80 25/03/2022 Adjusted towards trip 3130
14 PAID 50  26/03/2022 Given to Nate Cash (padma ac) 3180

最初の数字を無視するか、最初の単語にリンクしたいと思います。次に、最初の単語をダッシュ​​/ハイフンにリンクし、日付を入力してから単語を入力します。数字を追加するので、新しい行を除いてスペースを削除します。

Linuxノートブックに簡単にインストールして実行できるスクリプト、perl / php、bash、awk、sedなどがあります。

出力サンプル

Paid;100;15/02/2022;3000
recd;50;15/02/2022;nelur-trip;3050
PAID;80;25/03/2022;Adjusted-towards-trip;3130
14-PAID;50;26/03/2022;Given-to-Nate-Cash-(padma-ac);3180

これをスプレッドシートにインポートしたいので、他の方法も可能です。約300行があります。

以前は何を試しましたか?スプレッドシートを使用して、画像と画像 - テキストコンバータから得られたデータをクリーンアップします。

また、notepad++と列選択を試してみました。私はすぐにAWKを学びようとしました。私はJavaを知っていますが、時間がかかります。答えを受けた後、いくつかの事実を学びました。

  1. 行番号がある場合、それを維持することで、awkを使用するときにどの行が欠落しているかを判断するのに役立ちます。 ASはスキップされた行を警告せずに出力を提供します。たぶんそれをバイパスする設定かもしれませんが、わかりません。
  2. csv、スプレッドシート、またはPDF形式のアカウントは常に要求され、画像は許可されていません!

私たちのアカウントの友達から受け取った画像に画像をテキストとして実行して入力を受け取ります。

答え1

perl -pe 's/(?:^[0-9]+|[^0-9])\K (?=[^0-9])/-/g;
          s/ /;/g
' -- file
  • -p入力を1行ずつ読み、処理後に各行を印刷します。
  • 最初の置換はLookaroundアサーションを使用します。文字列の先頭にスペースの前に数字があるか、数字ではないが後ろに数字がない場合は、スペースをダッシュ​​に置き換えます。;
  • 2番目の置換は、残りのスペースをセミコロンで置き換えます。

最後の行の後の2つのスペースが誤字でない場合は、2番目の置換を変更して、隣接するすべてのスペースを単一のセミコロンに置き換える必要があり50ます。s/ +/;/g

答え2

今答えを得ました...

3番目の引数としてGNU awkを使用してくださいmatch()

awk -v OFS=';' '
    match($0,/\S\s+([0-9]+)\s+(([0-9]{2}\/){2}[0-9]{4})(\s+(.*\S))? ([0-9]+)$/,a) {
        $0 = substr($0,1,RSTART) OFS a[1] OFS a[2] OFS a[5] OFS a[6]
        gsub(/\s+/,"-")
        print
    }
' file
Paid;100;15/02/2022;;3000
recd;50;15/02/2022;nelur-trip;3050
PAID;80;25/03/2022;Adjusted-towards-trip;3130
14-PAID;50;26/03/2022;Given-to-Nate-Cash-(padma-ac);3180

上記は、入力形式が次のとおりであると仮定しています。

<anything1> <integer1> <date>[ <anything2>] <integer2>
  (.*\S)     ([0-9]+)     ^    ( (.*\S))?    ([0-9]+)
                          |
              (([0-9]{2}\/){2}[0-9]{4})

フィールド間に改行以外の空白がある可能性がある場合、anything内部フィールドは常に空白ではないことで終わりますが、スペースやその他の文字を含めることができ、整数の前にある日付文字列を含めることは<...>できません。と同じだとしましょう。anything1[ <anything2>]

<anything1>;<integer1>;<date>;<anything2>;<integer2>

これはPaid;100;15/02/2022;3000、期待される出力で実際にPaid;100;15/02/2022;;3000次のようになるはずです。各出力行には、OPが欲しいと述べたように、スプレッドシートを取得するために使用されるフィールド数が同じでなければなりません。

\S正規表現の先頭に単一を使用し、もともと予想したように配列要素を埋めるのではなく、substr()ヘッダー文字列を取得するために使用しており、これが失敗することに気付いたので、質問に投稿された入力例を使用します。与えられた入力、例えば:anything(.*\S)

Paid 100 15/02/2022 foo 100 15/02/2022 3000

ここで、行には2つの日付があり、2番目の日付の周りの文字列は残りの正規表現と一致します。たとえば、この修正された入力と一番下の問題の行は次のようになります。

$ cat file
Paid 100 15/02/2022 3000
recd 50 15/02/2022 nelur trip 3050
PAID 80 25/03/2022 Adjusted towards trip 3130
14 PAID 50  26/03/2022 Given to Nate Cash (padma ac) 3180
Paid 100 15/02/2022 foo 100 15/02/2022 3000

(.*\S)正規表現の先頭に使用する場合は、望ましくない最後の出力行に注意してください。

$ awk -v OFS=';' '
    match($0,/(.*\S)\s+([0-9]+)\s+(([0-9]{2}\/){2}[0-9]{4})(\s+(.*\S))? ([0-9]+)$/,a) {
        $0 = a[1] OFS a[2] OFS a[3] OFS a[6] OFS a[7]
        gsub(/\s+/,"-")
        print
    }
' file
Paid;100;15/02/2022;;3000
recd;50;15/02/2022;nelur-trip;3050
PAID;80;25/03/2022;Adjusted-towards-trip;3130
14-PAID;50;26/03/2022;Given-to-Nate-Cash-(padma-ac);3180
Paid-100-15/02/2022-foo;100;15/02/2022;;3000

提案されたスクリプトを使用して出力を変更します。

$ awk -v OFS=';' '
    match($0,/\S\s+([0-9]+)\s+(([0-9]{2}\/){2}[0-9]{4})(\s+(.*\S))? ([0-9]+)$/,a) {
        $0 = substr($0,1,RSTART) OFS a[1] OFS a[2] OFS a[5] OFS a[6]
        gsub(/\s+/,"-")
        print
    }
' file
Paid;100;15/02/2022;;3000
recd;50;15/02/2022;nelur-trip;3050
PAID;80;25/03/2022;Adjusted-towards-trip;3130
14-PAID;50;26/03/2022;Given-to-Nate-Cash-(padma-ac);3180
Paid;100;15/02/2022;foo-100-15/02/2022;3000

コメントのフィードバックに基づいて編集してください。正規表現と一致しない行を記録してください。

awk -v OFS=';' '
    match($0,/\S\s+([0-9]+)\s+(([0-9]{2}\/){2}[0-9]{4})(\s+(.*\S))? ([0-9]+)$/,a) {
        $0 = substr($0,1,RSTART) OFS a[1] OFS a[2] OFS a[5] OFS a[6]
        gsub(/\s+/,"-")
        print
        next
    }
    { print > "/dev/stderr" }
' file 2>unmatched.log

答え3

sed -E 's,([^0-9 ]) +([^0-9 ]),\1-\2,g
        s,^([0-9]+) +,\1-,g
        s, +,;,g
'

答え4

使用幸せ(以前のPerl_6)

まず、解析するすべての行を取得できることを確認してください。

~$ raku -ne '.match(/ ^ \d* \s? <.alpha>+ \s \d+ \s [ \d**2 \/ \d**2 \/ \d**4 ] \s [[<.graph>+]+ % " " \s]? \d+ $ /).say;'  file

上記は、Perlプログラミング言語スイートの中でUnicodeをサポートするRakuの1つのアプローチです。複雑な正規表現の問題で始まるので、最初から最後まですべての行が正しく解析されていることを確認するのが最善です/^ … $/。 (raku -pe 's:g/\s+/ /;'まず、空白の正規化などのタスクを実行する必要があるかもしれません)。上記のコードは、NilOPの結果である正しく解析されていない行を返します。空の正規化データ:

入力例:

Paid 100 15/02/2022 3000
recd 50 15/02/2022 nelur trip 3050
PAID 80 25/03/2022 Adjusted towards trip 3130
14 PAID 50 26/03/2022 Given to Nate Cash (padma ac) 3180

解析ライン:

「Paid 100 15/02/2022 3000」
「recd 50 15/02/2022 nelur trip 3050」
「PAID 80 25/03/2022 Adjusted towards trip 3130」
「14 PAID 50 26/03/2022 Given to Nate Cash (padma ac) 3180」

これで、すべての行が最初から最後まで解析され、一致する要素をキャプチャできることがわかります。キャプチャを表すには、かっこを使用します。 Rakuキャプチャは次から始まります$0

~$ raku -ne '.match(/ ^ (\d* \s? <.alpha>+) \s (\d+) \s ( \d**2 \/ \d**2 \/ \d**4 ) \s [(<.graph>+)+ % " " \s]? (\d+) $ /).say;'  file
「Paid 100 15/02/2022 3000」
 0 => 「Paid」
 1 => 「100」
 2 => 「15/02/2022」
 4 => 「3000」
「recd 50 15/02/2022 nelur trip 3050」
 0 => 「recd」
 1 => 「50」
 2 => 「15/02/2022」
 3 => 「nelur」
 3 => 「trip」
 4 => 「3050」
「PAID 80 25/03/2022 Adjusted towards trip 3130」
 0 => 「PAID」
 1 => 「80」
 2 => 「25/03/2022」
 3 => 「Adjusted」
 3 => 「towards」
 3 => 「trip」
 4 => 「3130」
「14 PAID 50 26/03/2022 Given to Nate Cash (padma ac) 3180」
 0 => 「14 PAID」
 1 => 「50」
 2 => 「26/03/2022」
 3 => 「Given」
 3 => 「to」
 3 => 「Nate」
 3 => 「Cash」
 3 => 「(padma」
 3 => 「ac)」
 4 => 「3180」

最終回答 - Raku.subst( /…/, {…} )またはRakuのs///代替コマンド/イディオムを使用してください。注:両方の代替イディオムは、置き換え時に中括弧内に「呼​​び出し可能」コードを配置することで、各コマンドの機能を大幅に向上させます。したがって、.trans残りの空白文字を-ハイフンに追加してからjoinセミコロンに追加できます;

~$ raku -ne '.subst(/ ^ (\d* \s? <.alpha>+) \s (\d+) \s ( \d**2 \/ \d**2 \/ \d**4 ) \s [(<.graph>+)+ % " " \s]? (\d+) $/,  \
             {join ";", $0.trans(" " => "-"), $1, $2, $3.trans(" " => "-") // "", $4}).put;'  file

#OR:

~$ raku -pe 's/ ^ (\d* \s? <.alpha>+) \s (\d+) \s ( \d**2 \/ \d**2 \/ \d**4 ) \s [(<.graph>+)+ % " " \s]? (\d+) $  \
              /{join ";", $0.trans(" " => "-"), $1, $2, $3.trans(" " => "-") // "", $4}/;'  file

出力例(上記の解決策の1つ):

Paid;100;15/02/2022;;3000
recd;50;15/02/2022;nelur-trip;3050
PAID;80;25/03/2022;Adjusted-towards-trip;3130
14-PAID;50;26/03/2022;Given-to-Nate-Cash-(padma-ac);3180

ボーナスポイント:はい標準化{$0.uc}最初の列をすべて等に変換するようPAIDRECDものを使用する場合

仮定の簡略化:正規表現を単純化することで\d数字\D以外の項目を処理できますが、英国の郵便番号や航空会社の確認コード(特に列4の中間)など、数字/数字以外の「単語」が混在する行を解析できません。かもしれません。 )。

https://docs.raku.org/routine/subst#Callable
https://docs.raku.org/言語/regexes
https://raku.org

関連情報