単一文字インスタンスに一致する正規表現

単一文字インスタンスに一致する正規表現

私は職場でこれを維持しており、やや難解なDSLを使用しています。そしてそのツールはあまり良くありません。誤ったツーリングの問題を解決するために、コードを本番に送信する前に、コード内のいくつかの問題を見つけるスクリプトを作成しました。

私が現在解決しようとしている問題は変数名に関連しています。変数名は次のように指定されます@@Variable@@。 1秒しかないか@2秒以上の場合、@致命的なエラーです。

問題のファイルを繰り返しながら連続して@@@3つ以上を検出すると、エラーが発生します@。だからその部分がかっこいいです。

しかし、私は独身生活に少し閉じ込められています@。 1行に複数の変数がある可能性があります。

@@Var1@@ words words words @@Var2@@  #This works
@Var1@@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@@ words words words @Var2@@   #This will fail because Var2 is wrong.
@@Var1@@ words words words @@Var2@   #This will fail because Var2 is wrong.

上記の置換はさまざまであり、1行の変数の数に制限はありません。

このawkスクリプトは、特定の行に変数が1つしかない場合は機能しますが、1行に複数の変数がある場合は機能しません。

awk '/@/ && ! /@@.*@@/' test.txt

実際にやるべきことは1つだけ一致させることです@。上記のサンプルコードは、行1を除くすべての行と一致します。

答え1

$ sed 'h;s/@@[^@ ]*@@//g;/@/!d;g' file
@Var1@@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@@ words words words @Var2@@   #This will fail because Var2 is wrong.
@@Var1@@ words words words @@Var2@   #This will fail because Var2 is wrong.

このsedコマンドは有効な変数プレースホルダを削除し、まだ文字を含む行を報告します@。また、@両側に複数のプレースホルダを含む行を探します。

各行を予約済みスペースに保存して、元の失敗した行を報告できますh。次に、潜在的に有効なプレースホルダを削除する置換を実行し、その後に文字が含まれていない場合は行を@削除します。予約済みスペースから元の行を取得し、存在するg場合は印刷します。

変数がほとんどのプログラミング言語と同じ命名規則に従う場合は、@@[^@ ]*@@有効なプレースホルダーのパターンをに変更できます。@@[[:alpha:]_][[:alnum:]_]*@@

@テキスト自体に文字を含めることができる必要があるとします。この場合、@上記のコマンドで置き換える前に、変数プレースホルダではなく有効な星座のすべての可能なエントリを削除する必要があります。


@より体系的なアプローチは、一方または他方に文字が多すぎるプレースホルダを含む行を抽出し、正しいプレースホルダを削除してから、変数名@OKの両側に1文字だけを含むようにプレースホルダを取得することです。

sed -e '/@\{3,\}[^@ ]*@\{1,\}/b' \
    -e '/@\{1,\}[^@ ]*@\{3,\}/b' \
    -e h \
    -e 's/@@[^@ ]*@@//g' \
    -e '/@[^@ ]*@/!d' \
    -e g file

@上記の方法では、文字がプレースホルダのように見えるパターンで表示されていない限り、テキストに他の文字を含めることができます。

答え2

$ grep -E '(^|[^@])@([^@]|$)|@@@' file
@Var1@@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@@ words words words @Var2@@   #This will fail because Var2 is wrong.
@@Var1@@ words words words @@Var2@   #This will fail because Var2 is wrong.

または:

$ awk '/(^|[^@])@([^@]|$)|@@@/' file
@Var1@@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@@ words words words @Var2@@   #This will fail because Var2 is wrong.
@@Var1@@ words words words @@Var2@   #This will fail because Var2 is wrong.

または、一度に1つのフィールドを分析します。

$ cat tst.awk
{
    for (i=1; i<=NF; i++) {
        if ( $i ~ /^@[^@]|[^@]@$|@@@/ ) {
            print "Failed line:", NR, $0
            print "\tbecause of field", i, $i
        }
    }
}

$ awk -f tst.awk file
Failed line: 2 @Var1@@ words words words @@Var2@@   #This will fail because Var1 is wrong.
        because of field 1 @Var1@@
Failed line: 3 @@Var1@ words words words @@Var2@@   #This will fail because Var1 is wrong.
        because of field 1 @@Var1@
Failed line: 4 @@Var1@@ words words words @Var2@@   #This will fail because Var2 is wrong.
        because of field 5 @Var2@@
Failed line: 5 @@Var1@@ words words words @@Var2@   #This will fail because Var2 is wrong.
        because of field 5 @@Var2@

イベントを見つけるために必要なものは何もなく、上記には@@@イベントの検索も含まれます。

答え3

別の解決策は、正規grep -E表現がawkでも機能することです。

grep -E '[^@]@[^@]|^@[^@]|@[^@]$' tmpfile
@Var1@@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@@ words words words @Var2@@   #This will fail because Var2 is wrong.
@@Var1@@ words words words @@Var2@   #This will fail because Var2 is wrong.

awk '/[^@]@[^@]|^@[^@]|@[^@]$/' tmpfile
@Var1@@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@@ words words words @Var2@@   #This will fail because Var2 is wrong.
@@Var1@@ words words words @@Var2@   #This will fail because Var2 is wrong.

答え4

サポートされている場合は、負のナビゲーション演算子を使用して、単一のsまたはgrep -Psで囲まれていない@3つ以上のシーケンスを一致させることができます。@@

<test.txt grep --color -P '(?<!@)(@|@{3,})(?!@)'

ただし、これはまだ表示され、@@@@inやなどの@@var1@@@@var2@@一致しないsを表示することはできません。@@@@var1@@var1@@var2@@

別の方法は次のとおりです。

<test.txt grep --color -P '@@\w+@@(*SKIP)(*FAIL)|@+'

これはシーケンスの@一部ではない部分を示します。@@word@@

$ <test.txt grep --color -P '@@\w+@@(*SKIP)(*FAIL)|@+' @Var1@@ 単語の単語 @​​@Var2@@ #Var1 がエラーなので失敗します。の。 @@Var1@wordswords@@Var2@@#Var1が間違っているため失敗します。 @@Var1@@wordswords@Var2@@#Var2が間違っているため失敗します。 @@Var1@@wordswords@@Var2@#Var2が間違っているため失敗します。

関連情報