与えられたサフィックスで終わっていない文字列の正規表現


188

ある条件で終わっていない文字列に一致する適切な正規表現を見つけることができませんでした。たとえば、末尾がa。であるものには一致させたくありません。

これは一致します

b
ab
1

これは一致しません

a
ba

その前に$何が必要かわからないが、私は正規表現が終わりを示すために終わるべきであることを知っています。

編集:元の質問は私の場合の正当な例ではないようです。では、複数の文字をどのように処理するのでしょうか?で終わらないものは何abですか?

私はこのスレッドを使用してこれを修正することができました:

.*(?:(?!ab).).$

これの欠点は1文字の文字列と一致しないことです。


5
これは、リンクされた質問の複製ではありません。末尾のみとのマッチングには、文字列内のどこかでのマッチングとは異なる構文が必要です。ここで一番上の答えを見てください。
ジャスティン

これはリンクされた質問の複製ではありません。上記の「マーク」を削除するにはどうすればよいですか。
アランカブレラ2015年

私が見ることができるようなリンクはありません。
アランカブレラ

回答:


249

あなたは私たちに言語を与えませんが、正規表現フレーバーのサポートがアサーションの背後にある場合、これが必要です:

.*(?<!a)$

(?<!a)文字列(またはm修飾子付きの行)の終わりの前に文字 "a"がないことを保証する否定後読みアサーションです。

それを参照してくださいRegexrにここに

このチェックは文字列であり、文字クラスではないため、これを他の文字で簡単に拡張することもできます。

.*(?<!ab)$

これは「ab」で終わらないものと一致します。Regexr確認してください


1
RegexPALは知りませんが、正規表現はすべての言語で異なり、後読みアサーションは高度な機能であり、すべてではサポートされていません。
Stea 2013年

7
regexpalはjavascriptベースのregexテスターであり、javascriptは悲しい後読みアサーションをサポートしていません
HamZa

後読みは正規表現ではサポートされていません(JavaScript)
Stealth Rabbi

1
JSに後読みがないと、私は泣きます。サーバー側で実行している場合でも、おそらくNPMなどでPCREモジュールを使用して直接使用できます(バインディングのセットであるため、フロントエンドを使用できないと思います)
Eirik Birkeland

その他の先読み/後読みアサーションのタイプ:stackoverflow.com/q/2973436/12484
Jon Schneider

76

not^)記号を使用します。

.*[^a]$

^大括弧の先頭に記号を置くと、「大括弧内のものを除くすべて」を意味します。$単に終わりへのアンカーです。

複数の文字の場合は、それらすべてを独自の文字セットに配置します。

.*[^a][^b]$

1
+1。これは空の文字列(意図したとおりである場合とそうでない場合がある)に一致しないことに注意してください。したがって、意味は「角かっこにない任意の文字」です。
Fred Foo

3
@ 0A0D:空白を含む文字列は空の文字列ではありません。
Fred Foo 2013年

7
@ 0A0D実際、それは議論の余地はありません、それは事実です
tckmn

8
@Doorknob:一致していませんaecb
Fred Foo 2013年

1
いいえ、これは "acb"も許可しません。
Menno 2013年

48

「.tmp」で終わらないファイルを検索するには、次の正規表現を使用します。

^(?!.*[.]tmp$).*$

Regexテスターでテストすると、次の結果が得られます。

ここに画像の説明を入力してください


1
これは興味深い^.*(?![.]tmp$)です。なぜこれが機能するのか、なぜ機能しないのでしょうか。
ルカシュZaroda

4
アーリー.*はすでに文字列全体と一致しているため、残りの除外は機能しません。
FiveO 2017

私の目的では、これはうまくいきましたが、他の答えはうまくいきませんでした。ありがとう!
David Moritz、

8
.*[^a]$

上記の正規表現は、末尾がでない文字列に一致しますa


元の例が私のケースと完全に一致していないようだったので、質問を拡張しました。解けますか
Menno 2013年

5

これを試して

/.*[^a]$/

[]文字クラスを示し、^反転文字クラスは、すべてのものが、一致しますa


1

質問は古いですが、私がここに投稿したより良い解決策を見つけることができませんでした。すべてのUSBドライブを検索しますが、パーティションの一覧は表示しないため、結果から「part [0-9]」を削除します。私は2つのgrepを実行することになり、最後は結果を否定しました:

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -vE "part[0-9]*$"

これは私のシステムでの結果です:

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

パーティションのみが必要な場合は、次のことができます。

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -E "part[0-9]*$"

私が入手する場所:

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part1
pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part2

そして私がするとき:

readlink -f /dev/disk/by-path/pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

私は得ます:

/dev/sdb

1

ルックアラウンドを使用できる場合は、受け入れられた回答で問題ありません。ただし、この問題を解決する別の方法もあります。

この質問に対して広く提案されている正規表現を見てみると、

.*[^a]$

それはほとんど動作することがわかります。空の文字列は受け入れられません。これは少し不便かもしれません。ただし、これは1文字だけを扱う場合のマイナーな問題です。ただし、「abc」などの文字列全体を除外する場合は、次のようにします。

.*[^a][^b][^c]$

しません。たとえば、acは受け付けません。

ただし、この問題には簡単な解決策があります。簡単に言うと:

.{,2}$|.*[^a][^b][^c]$

またはより一般的なバージョン:

.{,n-1}$|.*[^firstchar][^secondchar]$ ここで、nあなたは(のために禁止したい文字列の長さであるabc、それは3ですが)、そしてfirstcharsecondchar...(のためのあなたの文字列の第一、第二... n番目の文字であるabcことは次のようになりa、その後、bその後、c)。

これは、禁止しないテキストよりも短い文字列には、定義上このテキストを含めることができないという単純な観察から来ています。したがって、短いもの( "ab"は "abc"ではない)を受け入れることも、最後まで受け入れずに受け入れることができる長さを受け入れることもできます。

.jpg以外のすべてのファイルを削除するfindの例を次に示します。

find . -regex '.{,3}$|.*[^.][^j][^p][^g]$' -delete


.{,2}$|.*[^a][^b][^c]$一致しませんccc
psalaets

0

-で終わるものに一致するもの--- .*a$したがって、正規表現に一致する場合、条件を否定するか、代わりに.*[^a]$どこ[^a]でも実行できますnot a


0

を使用しているgrep場合sed、または構文が少し異なります。順次[^a][^b]メソッドはここでは機能しないことに注意してください。

balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n'
jd8a
8$fb
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a]$"
8$fb
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b]$"
jd8a
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^c]$"
jd8a
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a][^b]$"
jd8a
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a][^c]$"
jd8a
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a^b]$"
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a^c]$"
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b^c]$"
jd8a
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b^c^a]$"

FWIW、私はRegex101で同じ結果を見つけています。これはJavaScript構文だと思います。

悪い:https : //regex101.com/r/MJGAmX/2
良い:https : //regex101.com/r/LzrIBu/2

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.