単語を含まない行に一致する正規表現

4493
knaser 2009-01-02 21:30.

単語を一致させてから、他のツール(例grep -v)を使用して一致を逆にすることが可能であることを私は知っています。ただし、hede正規表現を使用して、特定の単語を含まない行を照合することは可能ですか?

入力:

hoho
hihi
haha
hede

コード:

grep "<Regex for 'doesn't contain hede'>" input

必要な出力:

hoho
hihi
haha

30 answers

6170
Bart Kiers 2009-01-02 23:55.

正規表現が逆マッチングをサポートしていないという考えは完全には真実ではありません。ネガティブルックアラウンドを使用することで、この動作を模倣できます。

^((?!hede).)*$

上記の正規表現は、改行せずに任意の文字列、又は行と一致しますない(サブ)文字列「hede」を含みます。前述のように、これは正規表現がで「良い」である(あるいはやるべき)ものではありませんが、それでも、それがある可能。

また、改行文字も一致させる必要がある場合は、DOT-ALL修飾子(s次のパターンの末尾)を使用します。

/^((?!hede).)*$/s

またはインラインで使用します。

/(?s)^((?!hede).)*$/

/.../正規表現の区切り文字があります。つまり、パターンの一部ではありません)

DOT-ALL修飾子が使用できない場合は、文字クラスで同じ動作を模倣できます[\s\S]

/^((?!hede)[\s\S])*$/

説明

文字列は単なる文字のリストですn。各文字の前後に、空の文字列があります。したがって、n文字のリストにはn+1空の文字列が含まれます。文字列を考えてみましょう"ABhedeCD"

    ┌──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┐
S = │e1│ A │e2│ B │e3│ h │e4│ e │e5│ d │e6│ e │e7│ C │e8│ D │e9│
    └──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┘

index    0      1      2      3      4      5      6      7

ここで、e'は空の文字列です。正規表現(?!hede).は、表示"hede"される部分文字列がないかどうかを先読みします。その場合(他の何かが表示される)、.(ドット)は改行を除くすべての文字に一致します。ルックアラウンドは、文字を消費しないため、ゼロ幅アサーションとも呼ばれます。彼らは何かを主張/検証するだけです。

したがって、私の例では"hede"、文字が.(ドット)によって消費される前に、すべての空の文字列が最初に検証されて、前方に文字列がないかどうかが確認されます。正規表現(?!hede).はこれを1回だけ実行するため、グループにラップされ、0回以上繰り返されます((?!hede).)*。最後に、入力の開始と終了を固定して、入力全体が確実に消費されるようにします。^((?!hede).)*$

あなたが見ることができるように、入力が"ABhedeCD"あるために失敗するe3正規表現は、(?!hede)失敗した(そこ "hede"先にアップ!)。

774
FireCoding 2011-03-17 18:21.

の解決策は「hede」始まらないことに注意してください。

^(?!hede).*$

一般に「hede」を含まないソリューションよりもはるかに効率的です。

^((?!hede).)*$

前者は、すべての位置ではなく、入力文字列の最初の位置でのみ「hede」をチェックします。

213
Athena 2009-01-02 21:41.

grepに使用しているだけの場合grep -v hedeは、hedeを含まないすべての行を取得するために使用できます。

ETAああ、質問を読み直すと、grep -vおそらく「ツールオプション」が意味するものです。

169
Jessica 2014-05-11 06:36.

回答:

^((?!hede).)*$

説明:

^文字列の先頭、(グループ化、および\ 1へのキャプチャ(0回以上(可能な限り多くの量に一致))、
(?!存在しないかどうかを確認します。

hede あなたのひも、

)先読みの終わり、.\ n以外の任意の文字
)*、\ 1の終わり(注:このキャプチャで数量詞を使用しているため、キャプチャされたパターンの最後の繰り返しのみが\ 1に格納され
$ます)オプションの\ n、と文字列の終わり

104
Hades32 2011-09-03 05:53.

与えられた答えは完全に問題なく、学術的なポイントにすぎません。

理論計算機科学の意味での正規表現は、このようにすることはできません。彼らにとって、それはこのように見えなければなりませんでした:

^([^h].*$)|(h([^e].*$|$))|(he([^h].*$|$))|(heh([^e].*$|$))|(hehe.+$) 

これは完全一致のみを行います。サブマッチのためにそれをすることはさらに厄介でしょう。

64
Roy Tinker 2013-01-04 11:22.

文字列全体が一致する場合にのみ正規表現テストを失敗させたい場合は、以下が機能します。

^(?!hede$).*

例-「foo」以外のすべての値を許可する場合(つまり、「foofoo」、「barfoo」、および「foobar」は成功しますが、「foo」は失敗します)、次を使用します。 ^(?!foo$).*

もちろん、完全に等しいかどうかをチェックする場合、この場合のより一般的な解決策は、文字列の等しいかどうかをチェックすることです。

myStr !== 'foo'

正規表現機能(ここでは、大文字と小文字の区別と範囲の一致)が必要な場合は、否定をテストの外に置くこともできます。

!/^[a-f]oo$/i.test(myStr)

ただし、この回答の上部にある正規表現ソリューションは、(おそらくAPIによって)陽性の正規表現テストが必要な状況で役立つ場合があります。

57
akim 2015-08-05 21:02.

FWIW、正規言語(別名有理言語)は補完の下で閉じられているため、別の式を否定する正規表現(別名有理式)を見つけることは常に可能です。しかし、これを実装するツールは多くありません。

Vcsnはこの演算子をサポートしています(これは{c}、後置を示します)。

ラベルは(手紙です:あなたは、最初に自分の表現のタイプを定義lal_charから選択する)az(相補性で作業する場合、アルファベットを定義することは、当然のことながら、非常に重要である)は、例えば、各単語に対して計算され、「値が」単なるブール値です:true単語は受け入れられfalse、、拒否されます。

Pythonの場合:

In [5]: import vcsn
        c = vcsn.context('lal_char(a-z), b')
        c
Out[5]: {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z} → 𝔹

次に、式を入力します。

In [6]: e = c.expression('(hede){c}'); e
Out[6]: (hede)^c

この式をオートマトンに変換します。

In [7]: a = e.automaton(); a

最後に、このオートマトンを単純な式に変換し直します。

In [8]: print(a.expression())
        \e+h(\e+e(\e+d))+([^h]+h([^e]+e([^d]+d([^e]+e[^]))))[^]*

ここで、+は通常、で示され|\e空の単語を示し、[^]通常は書き込まれます.(任意の文字)。だから、少し書き直して()|h(ed?)?|([^h]|h([^e]|e([^d]|d([^e]|e.)))).*

この例はここで確認でき、Vcsnをオンラインで試してみてください。

56
Josh Lee 2009-01-02 22:03.

ここだ良い説明それは任意の正規表現を否定することは容易ではありません理由のは。ただし、他の回答にも同意する必要があります。これが架空の質問以外の場合、正規表現はここでは正しい選択ではありません。

51
amobiz 2014-07-15 08:21.

負の先読みを使用すると、正規表現は特定のパターンを含まないものと一致する可能性があります。これはBartKiersによって回答され、説明されています。素晴らしい説明です!

ただし、Bart Kiersの回答では、先読み部分は1〜4文字先をテストし、任意の1文字を照合します。これを回避して、先読み部分にテキスト全体をチェックさせ、「hede」がないことを確認すると、通常の部分(。*)がテキスト全体を一度に食べることができます。

改善された正規表現は次のとおりです。

/^(?!.*?hede).*$/

負の先読み部分の(*?)遅延数量詞はオプションであることに注意してください。データに応じて、代わりに(*)貪欲数量詞を使用できます。「hede」が存在し、テキストの前半にある場合、遅延数量詞は次のようになります。より速くなります。それ以外の場合は、欲張り数量詞の方が高速です。ただし、「hede」が存在しない場合は、両方とも同じように遅くなります。

これがデモコードです。

先読みの詳細については、すばらしい記事「先読みと後読みの習得」をご覧ください。

また、複雑な正規表現の作成に役立つJavaScript正規表現ジェネレーターであるRegexGen.jsも確認してください。RegexGen.jsを使用すると、より読みやすい方法で正規表現を作成できます。

var _ = regexGen;

var regex = _(
    _.startOfLine(),             
    _.anything().notContains(       // match anything that not contains:
        _.anything().lazy(), 'hede' //   zero or more chars that followed by 'hede',
                                    //   i.e., anything contains 'hede'
    ), 
    _.endOfLine()
);
43
Falco 2014-08-14 04:58.

ベンチマーク

提示されたオプションのいくつかを評価し、それらのパフォーマンスを比較し、いくつかの新しい機能を使用することにしました。.NET Regex Engineでのベンチマーク:http://regexhero.net/tester/

ベンチマークテキスト:

最初の7行は検索された式が含まれているため一致しないはずですが、下の7行は一致する必要があります。

Regex Hero is a real-time online Silverlight Regular Expression Tester.
XRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex HeroRegex HeroRegex HeroRegex HeroRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her Regex Her Regex Her Regex Her Regex Her Regex Her Regex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her is a real-time online Silverlight Regular Expression Tester.Regex Hero
egex Hero egex Hero egex Hero egex Hero egex Hero egex Hero Regex Hero is a real-time online Silverlight Regular Expression Tester.
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRegex Hero is a real-time online Silverlight Regular Expression Tester.

Regex Her
egex Hero
egex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her is a real-time online Silverlight Regular Expression Tester.
Regex Her Regex Her Regex Her Regex Her Regex Her Regex Her is a real-time online Silverlight Regular Expression Tester.
Nobody is a real-time online Silverlight Regular Expression Tester.
Regex Her o egex Hero Regex  Hero Reg ex Hero is a real-time online Silverlight Regular Expression Tester.

結果:

結果は、3回の実行の中央値としての1秒あたりの反復数です-数値が大きいほど=良い

01: ^((?!Regex Hero).)*$ 3.914 // Accepted Answer 02: ^(?:(?!Regex Hero).)*$                  5.034   // With Non-Capturing group
03: ^(?>[^R]+|R(?!egex Hero))*$ 6.137 // Lookahead only on the right first letter 04: ^(?>(?:.*?Regex Hero)?)^.*$             7.426   // Match the word and check if you're still at linestart
05: ^(?(?=.*?Regex Hero)(?#fail)|.*)$       7.371   // Logic Branch: Find Regex Hero? match nothing, else anything

P1: ^(?(?=.*?Regex Hero)(*FAIL)|(*ACCEPT))  ?????   // Logic Branch in Perl - Quick FAIL
P2: .*?Regex Hero(*COMMIT)(*FAIL)|(*ACCEPT) ?????   // Direct COMMIT & FAIL in Perl

.NETはアクション動詞(* FAILなど)をサポートしていないため、ソリューションP1およびP2をテストできませんでした。

概要:

私はほとんどの提案された解決策をテストしようとしました、いくつかの最適化は特定の単語に対して可能です。たとえば、検索文字列の最初の2文字が同じでない場合、回答03を展開し^(?>[^R]+|R+(?!egex Hero))*$て、パフォーマンスをわずかに向上させることができます。

しかし、全体的に最も読みやすく、パフォーマンス面で最速のソリューションは、条件文を使用した05、または正の数量詞を使用した04のようです。Perlソリューションはさらに高速で読みやすいはずだと思います。

33
kiwalk 2011-02-24 04:00.

正規表現ではありませんが、ノイズを除去するためにパイプでシリアルグループを使用することは論理的で便利であることがわかりました。

例えば。すべてのコメントなしでApache設定ファイルを検索します-

grep -v '\#' /opt/lampp/etc/httpd.conf      # this gives all the non-comment lines

そして

grep -v '\#' /opt/lampp/etc/httpd.conf |  grep -i dir

シリアルgrepのロジックは(コメントではなく)および(dirに一致)です。

30
Casimir et Hippolyte 2013-04-14 17:04.

これにより、各位置で先読みをテストすることを回避できます。

/^(?:[^h]+|h++(?!ede))*+$/

(.netの場合)と同等:

^(?>(?:[^h]+|h+(?!ede))*)$

古い答え:

/^(?>[^h]+|h+(?!ede))*$/
24
ikegami 2016-08-23 14:03.

前述(?:(?!hede).)*は固定できるので素晴らしいです。

^(?:(?!hede).)*$               # A line without hede

foo(?:(?!hede).)*bar           # foo followed by bar, without hede between them

ただし、この場合は次のようにすれば十分です。

^(?!.*hede)                    # A line without hede

この簡略化では、「AND」句を追加する準備ができています。

^(?!.*hede)(?=.*foo)(?=.*bar)   # A line with foo and bar, but without hede
^(?!.*hede)(?=.*foo).*bar       # Same
21
ridgerunner 2013-12-20 17:03.

これが私がそれをする方法です:

^[^h]*(h(?!ede)[^h]*)*$

他の回答よりも正確で効率的です。これは、フリードルの「ループ展開」効率化手法を実装し、必要なバックトラックがはるかに少なくなります。

18
diyism 2012-03-23 21:24.

文字クラスを否定するのと同様の単語を否定するために文字を一致させたい場合:

たとえば、文字列:

<?
$str="aaa        bbb4      aaa     bbb7";
?>

使ってはいけません:

<?
preg_match('/aaa[^bbb]+?bbb7/s', $str, $matches);
?>

使用する:

<?
preg_match('/aaa(?:(?!bbb).)+?bbb7/s', $str, $matches);
?>

通知"(?!bbb)."は後読みでも先読みでもありません。たとえば、次のようになります。

"(?=abc)abcde", "(?!abc)abcde"
18
Dannie P 2018-11-25 08:26.

私の意見では、トップアンサーのより読みやすい変形:

^(?!.*hede)

基本的に、「行の先頭で一致するのは、「hede」が含まれていない場合のみ」です。したがって、要件はほぼ直接正規表現に変換されます。

もちろん、複数の障害要件が存在する可能性があります。

^(?!.*(hede|hodo|hada))

詳細: ^アンカーは、正規表現エンジンが文字列内のすべての場所で一致を再試行しないようにします。これにより、すべての文字列が一致します。

先頭の^アンカーは、行の先頭を表すことを意味します。grepツールは、各行を一度に1つずつ照合します。複数行の文字列を使用しているコンテキストでは、「m」フラグを使用できます。

/^(?!.*hede)/m # JavaScript syntax

または

(?m)^(?!.*hede) # Inline flag
14
Kevin Fegan 2013-04-27 12:28.

OPはTag、正規表現が使用されるコンテキスト(プログラミング言語、エディター、ツール)を指定または投稿しませんでした。

私の場合、を使用してファイルを編集しているときに、これを行う必要がある場合がありますTextpad

Textpad 一部の正規表現をサポートしますが、先読みまたは後読みをサポートしないため、いくつかの手順が必要です。

文字列を含まないすべての行を保持しhedeたい場合は、次のようにします。

1.ファイル全体を検索/置換して、テキストを含む各行の先頭に一意の「タグ」を追加します。

    Search string:^(.)  
    Replace string:<@#-unique-#@>\1  
    Replace-all  

2.文字列を含むすべての行を削除しますhede(置換文字列は空です)。

    Search string:<@#-unique-#@>.*hede.*\n  
    Replace string:<nothing>  
    Replace-all  

3.この時点で、残りのすべての行に文字列が含まれていませんhede。すべての行から一意の「タグ」を削除します(置換文字列は空です)。

    Search string:<@#-unique-#@>
    Replace string:<nothing>  
    Replace-all  

これで、文字列を含むすべての行がhede削除された元のテキストができました。


私がするのを楽しみにしていた場合は、何か他のものを実行してくださいということだけラインにDOはしない文字列が含まれているhede、私はこのようにそれを行うだろう。

1.ファイル全体を検索/置換して、テキストを含む各行の先頭に一意の「タグ」を追加します。

    Search string:^(.)  
    Replace string:<@#-unique-#@>\1  
    Replace-all  

2.文字列を含むすべての行についてhede、一意の「タグ」を削除します。

    Search string:<@#-unique-#@>(.*hede)
    Replace string:\1  
    Replace-all  

3.この時点で、一意の「タグ」で始まるすべての行に文字列を含めないくださいhede。私は今、それらの行だけに何か他のことをすることができます。

4.完了したら、すべての行から一意の「タグ」を削除します(置換文字列は空です)。

    Search string:<@#-unique-#@>
    Replace string:<nothing>  
    Replace-all  
14
Pedro Gimeno 2016-12-07 11:24.

尋ねられた質問に誰も直接答えていないので、私がやります。

答えは、POSIXではgrep、この要求を文字通り満たすことは不可能であるということです。

grep "<Regex for 'doesn't contain hede'>" input

その理由は、POSIXgrepは基本的な正規表現でのみ機能する必要があるためです。これは、そのタスクを実行するのに十分な能力がありません(代替がないため、すべての正規言語を解析することはできません)。

ただし、GNUgrepはそれを可能にする拡張機能を実装しています。特に、\|GNUのBREの実装における交代演算子です。正規表現エンジンが交互、括弧、およびクリーネ閉包をサポートし、文字列の最初と最後に固定できる場合、このアプローチに必要なのはそれだけです。ただし、ネガティブセット[^ ... ]は、それらに加えて非常に便利であることに注意してください。そうし(a|b|c| ... )ないと、セットに含まれていないすべての文字をリストするフォームの式に置き換える必要があります。これは、非常に面倒で長すぎるためです。文字セット全体がUnicodeです。

形式言語理論のおかげで、そのような表現がどのように見えるかを見ることができます。GNUを使用するgrepと、答えは次のようになります。

grep "^\([^h]\|h\(h\|eh\|edh\)*\([^eh]\|e[^dh]\|ed[^eh]\)\)*\(\|h\(h\|eh\|edh\)*\(\|e\|ed\)\)$" input

(Grailと手作業で行われたいくつかのさらなる最適化で見つかりました)。

のような拡張正規表現を実装するツールを使用してegrep、円記号を取り除くこともできます。

egrep "^([^h]|h(h|eh|edh)*([^eh]|e[^dh]|ed[^eh]))*(|h(h|eh|edh)*(|e|ed))$" input

これをテストするためのスクリプトがあります(testinput.txt現在のディレクトリにファイルが生成されることに注意してください)。提示された式のいくつかは、このテストに失敗します。

#!/bin/bash
REGEX="^\([^h]\|h\(h\|eh\|edh\)*\([^eh]\|e[^dh]\|ed[^eh]\)\)*\(\|h\(h\|eh\|edh\)*\(\|e\|ed\)\)$" # First four lines as in OP's testcase. cat > testinput.txt <<EOF hoho hihi haha hede h he ah head ahead ahed aheda ahede hhede hehede hedhede hehehehehehedehehe hedecidedthat EOF diff -s -u <(grep -v hede testinput.txt) <(grep "$REGEX" testinput.txt)

私のシステムでは、次のように出力されます。

Files /dev/fd/63 and /dev/fd/62 are identical

予想通り。

詳細に関心のある人のために採用された手法は、単語に一致する正規表現を有限オートマトンに変換し、すべての受け入れ状態を非受け入れに、またはその逆に変更することによってオートマトンを反転し、結果のFAをに変換することです。正規表現。

誰もが指摘しているように、正規表現エンジンが負の先読みをサポートしている場合、正規表現ははるかに単純です。たとえば、GNUgrepの場合:

grep -P '^((?!hede).)*$' input

ただし、このアプローチには、バックトラック正規表現エンジンが必要になるという欠点があります。これにより、RE2のような安全な正規表現エンジンを使用しているインストールには不適切になります。これは、状況によっては生成されたアプローチを好む理由の1つです。

Grailと同様の機能を提供するPHPで記述されたKendallHopkinsの優れたFormalTheoryライブラリと、自分で記述した単純化子を使用して、入力フレーズ(英数字とスペースのみ)を指定して負の正規表現のオンラインジェネレーターを記述できました。現在サポートされている文字):http://www.formauri.es/personal/pgimeno/misc/non-match-regex/

hedeそれが出力するために:

^([^h]|h(h|e(h|dh))*([^eh]|e([^dh]|d[^eh])))*(h(h|e(h|dh))*(ed?)?)?$

これは上記と同等です。

12
aelor 2017-03-24 03:42.

ruby-2.4.1の導入以来、Rubyの正規表現で新しい不在演算子を使用できるようになりました

公式ドキュメントから

(?~abc) matches: "", "ab", "aab", "cccc", etc.
It doesn't match: "abc", "aabc", "ccccabc", etc.

したがって、あなたの場合、あなたの^(?~hede)$ために仕事をします

2.4.1 :016 > ["hoho", "hihi", "haha", "hede"].select{|s| /^(?~hede)$/.match(s)}
 => ["hoho", "hihi", "haha"]
10
Avinash Raj 2014-10-09 21:00.

PCRE動詞を介して (*SKIP)(*F)

^hede$(*SKIP)(*F)|^.*$

これにより、正確な文字列を含む行が完全にスキップされhede、残りのすべての行に一致します。

デモ

パーツの実行:

上記の正規表現を2つの部分に分割して考えてみましょう。

  1. |記号の前の部分。パーツを一致させないでください

    ^hede$(*SKIP)(*F)
    
  2. |記号の後の部分。パーツを一致させる必要があります

    ^.*$
    

パート1

正規表現エンジンは、最初の部分から実行を開始します。

^hede$(*SKIP)(*F)

説明:

  • ^ 私たちが始めていることを主張します。
  • hede 文字列に一致します hede
  • $ 私たちが行末にいることを主張します。

したがって、文字列を含む行hedeが一致します。正規表現エンジンが次の(*SKIP)(*F)注:(*F)として記述できます(*FAIL))動詞を検出すると、スキップして一致を失敗させます。|PCRE動詞の横に追加された変更または論理OR演算子と呼ばれ、行に正確な文字列が含まれていることを除いて、すべての行のすべての文字の間に存在するすべての境界に一致しますhede。こちらのデモをご覧ください。つまり、残りの文字列の文字を一致させようとします。これで、2番目の部分の正規表現が実行されます。

パート2

^.*$

説明:

  • ^私たちが始めていることを主張します。つまり、行内の行を除くすべての行の開始に一致しますhede。こちらのデモをご覧ください。
  • .*マルチラインモードで.は、改行文字またはキャリッジリターン文字を除くすべての文字に一致します。そして*、前の文字を0回以上繰り返します。したがって.*、行全体に一致します。こちらのデモをご覧ください。

    なぜ。+の代わりに。*を追加したのですか?

    .*空白行と一致しますが、空白.+とは一致しないためです。を除くすべての行を一致させたいのでhede、入力にも空白行が含まれる可能性があります。したがって、の.*代わりにを使用する必要があります.+.+前の文字を1回以上繰り返します。ここで.*空白行に一致するを参照してください。

  • $ ここでは、行末アンカーは必要ありません。

9
Emma 2019-08-01 16:36.

もう1つのオプションは、前向きな先読みを追加hedeし、入力行のどこかにあるかどうかを確認することです。次に、次のような式でそれを否定します。

^(?!(?=.*\bhede\b)).*$

単語の境界があります。


式は、regex101.comの右上のパネルで説明されており、探索/簡略化/変更したい場合は、このリンクで、必要に応じて、いくつかのサンプル入力とどのように一致するかを確認できます。


正規表現回路

jex.imは正規表現を視覚化します。

8
andrew pate 2015-02-19 01:45.

コード内の2つの正規表現を維持する方が保守しやすい場合があります。1つは最初の一致を実行し、一致する場合は2番目の正規表現を実行して、たとえばブロックしたい外れ値のケースをチェック^.*(hede).*し、コードに適切なロジックを設定します。

OK、これは投稿された質問への回答ではなく、単一の正規表現よりもわずかに多くの処理を使用する可能性があることを認めます。しかし、外れ値のケースの迅速な緊急修正を探してここに来た開発者にとって、この解決策を見逃してはなりません。

6
Kaz 2014-06-25 15:23.

TXR言語は正規表現否定をサポートしています。

$ txr -c '@(repeat)
@{nothede /~hede/}
@(do (put-line nothede))
@(end)'  Input

より複雑な例:で始まり、aで終わるすべての行に一致しzますが、部分文字列は含まれませんhede

$ txr -c '@(repeat)
@{nothede /a.*z&~.*hede.*/}
@(do (put-line nothede))
@(end)' -
az         <- echoed
az
abcz       <- echoed
abcz
abhederz   <- not echoed; contains hede
ahedez     <- not echoed; contains hede
ace        <- not echoed; does not end in z
ahedz      <- echoed
ahedz

正規表現の否定は、それ自体では特に有用ではありませんが、交差がある場合は、ブール集合演算の完全なセットがあるため、物事が面白くなります。「これに一致するものを除いて、これに一致する集合」を表現できます。

4
Daniel Nyamasyo 2016-12-21 18:55.

以下の関数は、目的の出力を取得するのに役立ちます

<?PHP
      function removePrepositions($text){ $propositions=array('/\bfor\b/i','/\bthe\b/i'); 

            if( count($propositions) > 0 ) { foreach($propositions as $exceptionPhrase) { $text = preg_replace($exceptionPhrase, '', trim($text));

                }
            $retval = trim($text);

            }
        return $retval;
    }


?>
2
cloudhopperpilot 2019-03-27 02:21.

^((?!hede).)*$はエレガントなソリューションですが、文字を消費するため、他の基準と組み合わせることができません。たとえば、「hede」が存在しないことと「haha」が存在することを確認したいとします。このソリューションは、文字を消費しないため、機能します。

^(?!.*\bhede\b)(?=.*\bhaha\b) 
1
jaytea 2017-10-12 00:12.

PCREのバックトラッキング制御動詞を使用して単語を含まない行に一致させる方法

これは私が以前に使用したことのない方法です:

/.*hede(*COMMIT)^|/

使い方

まず、行のどこかで「hede」を見つけようとします。成功した場合、この時点(*COMMIT)で、障害が発生した場合にバックトラックするだけでなく、その場合はそれ以上のマッチングを試行しないようにエンジンに指示します。次に、一致する可能性のないもの(この場合は^)を一致させようとします。

行に「hede」が含まれていない場合、2番目の選択肢である空のサブパターンが件名の文字列と正常に一致します。

この方法はネガティブな先読みよりも効率的ではありませんが、誰かが気の利いたものを見つけて他のより興味深いアプリケーションに使用できる場合に備えて、ここに投げるだけだと思いました。

1
Matthew Rideout 2020-04-29 08:53.

文字列Xを含み、文字列Yも含まない行全体を照合しようとしている場合の別の例を追加したいと思います。

たとえば、URL /文字列に「tasty-treats」が含まれているかどうかを確認したいとします。ただし、「chocolate」もどこにも含まれていません。

この正規表現パターンは機能します(JavaScriptでも機能します)

^(?=.*?tasty-treats)((?!chocolate).)*$

(例ではグローバルな複数行フラグ)

インタラクティブな例: https://regexr.com/53gv4

マッチス

(これらのURLには「tasty-treats」が含まれており、「chocolate」も含まれていません)

  • example.com/tasty-treats/ストロベリーアイスクリーム
  • example.com/desserts/tasty-treats/banana-pudding
  • example.com/tasty-treats-overview

一致していません

(これらのURLにはどこかに「チョコレート」が含まれているため、「おいしいおやつ」が含まれていても一致しません)

  • example.com/tasty-treats/chocolate-cake
  • example.com/home-cooking/oven-roasted-chicken
  • example.com/tasty-treats/banana-chocolate-fudge
  • example.com/desserts/chocolate/tasty-treats
  • example.com/chocolate/tasty-treats/desserts
1
Anas R. 2020-06-16 01:02.

を処理している限り、単に負の一致をマークし、残りをターゲットにします

実際、このトリックはsedで^((?!hede).)*$サポートされていないように見えるため、sedで使用します。

希望する出力の場合

  1. hedeテキスト全体にまったく含まれていない文字を使用して、負の一致をマークします(例:)。この目的には、絵文字がおそらく良い選択かもしれません。

    s/(.*hede)/🔒\1/g
    
  2. 残りをターゲットにします(マークされていない文字列:例:のない行hede)。ターゲットのみ保持し、残りを(必要に応じて)削除するとします。

    s/^🔒.*//g
    

より良い理解のために

ターゲット削除したいとします:

  1. hedeテキスト全体にまったく含まれていない文字を使用して、負の一致をマークします(例:)。この目的には、絵文字がおそらく良い選択かもしれません。

    s/(.*hede)/🔒\1/g
    
  2. 残りをターゲットにします(マークされていない文字列:例:のない行hede)。ターゲット削除したいとします:

    s/^[^🔒].*//g
    
  3. マークを削除します。

    s/🔒//g
    
0
user1691651-John 2016-09-14 03:52.

より簡単な解決策は、not演算子を使用することです!

あなたの場合は文が一致する必要がありますし、「除外」と一致していない「が含まれて」。

var contains = /abc/;
var excludes =/hede/;

if(string.match(contains) && !(string.match(excludes))){  //proceed...

RegExの設計者は、not演算子の使用を予期していたと思います。

0
BrunoFacca 2018-04-26 08:15.

部分文字列を含まない行のセグメント(行全体ではなく)に一致することができる正規表現を書き込もうとしているときに、Googleでこれを見つけるかもしれませ。理解するのにしばらく時間がかかったので、共有します:

与えられた文字列: <span class="good">bar</span><span class="bad">foo</span><span class="ugly">baz</span>

<span>部分文字列「bad」を含まないタグを照合したい。

/<span(?:(?!bad).)*?>一致<span class=\"good\"><span class=\"ugly\">ます。

括弧には2つのセット(レイヤー)があることに注意してください。

  • 最も内側のものはネガティブルックアヘッド用です(キャプチャグループではありません)
  • 最も外側はRubyによってキャプチャグループとして解釈されましたが、キャプチャグループにしたくないので、最初に?:を追加し、キャプチャグループとして解釈されなくなりました。

Rubyでのデモ:

s = '<span class="good">bar</span><span class="bad">foo</span><span class="ugly">baz</span>'
s.scan(/<span(?:(?!bad).)*?>/)
# => ["<span class=\"good\">", "<span class=\"ugly\">"]

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

ねえNFL、ジョーバロウとカイラーマレーは女性の権利をサポートするために少しの助けを使うことができます

ねえNFL、ジョーバロウとカイラーマレーは女性の権利をサポートするために少しの助けを使うことができます

ジョー・バロウロー対ウェイド事件の転覆に対応するNFLは、言葉を言わないことで、腹立たしいが予測可能なPRの結果でした。

別の日、別のヒンジのないLIV記者会見

別の日、別のヒンジのないLIV記者会見

(lから)パット・ペレス、ブルックス・ケプカ、パトリック・リードサウジアラビアのLIVゴルフリーグのさらに別の信じられないほどの記者会見で、スポーツのファンはブルックス・ケプカからでたらめな吐き気と質問回避の驚異的なマスタークラスを受けました。パトリックリード、ブライソンデシャンボー、パットペレス、最近のPGAツアーの脱北者。

ミズ・マーベルの家族の帰郷は悪役よりも激しく打撃を与える

ミズ・マーベルの家族の帰郷は悪役よりも激しく打撃を与える

レッドダガーとマーベルさんがチームを組んでいます。

6億7500万ドルのビットコインローンのデフォルト後にすべての資産を清算するように命じられたスリーアローズキャピタル

6億7500万ドルのビットコインローンのデフォルト後にすべての資産を清算するように命じられたスリーアローズキャピタル

暗号業界最大の沈没船の1つであるスリーアローズキャピタルは、ついにその悲惨さから解放されています。火曜日に、不良債権ヘッジファンドは、債権者からの返済を要求する訴訟の高まりに応えて、バージンアイランド裁判所によって清算を命じられました彼らが3ACに行ったローン。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

Suffragettes Indicam #3: Junho

Suffragettes Indicam #3: Junho

Mais um mês se findando — e metade do ano de 2022 já passou. Sabe o que isso significa? Não, não é hora de verificar se você está cumprindo com suas resoluções de Ano Novo.

多元宇宙—Junø

多元宇宙—Junø

チェーン間アカウントがJunoに登場します。異なるブロックチェーン間でスマートコントラクトの構成可能性と真の相互運用性を提供します。

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

1.ドラマを見た後、起業する考えはありますか?あなたのビジネスはボトルネックに遭遇しましたか?方向性がなくてわからない場合は、ドラマを追いかけて行くことを心からお勧めします。(?)ブラフではなく、最も完璧なビジネス例を隠すドラマがあります。2.ブレイキング・バッドとその弁護士ドラマ「ブレイキング・バッド」を見た友人たちは、演劇の中で、穏やかな表情で、弁護士のソウル・グッドマンに深く感銘を受けなければなりません。口を開けて、感覚の弱い傭兵の性格を持っています。道徳の面で、サル・グッドマンは無意識のうちに劇に欠かせない役割を果たし、彼自身のシリーズ「絶望的な弁護士」(ベター・コール・ソール)を生み出しました。ウェントウのテキストとビデオは、劇中のソウル・グッドマンのテレビコマーシャルです。製品(サービス)、競争戦略、市場ポジショニング、ブランド名、ターゲット顧客グループ、コミュニケーション軸から広告まで、サル・グッドマンの役割のビジネス設定は、「最低」と見なすことができる超超超超超超完全です。ブランドコミュニケーションのコスト」「変化」のモデル。なぜ?私の分析をご覧ください。3.ソウル・グッドマンの「事業戦略」1.基本情報ブランド名:Saul Goodman製品:法律相談サービス対象顧客:麻薬中毒、飲酒運転、事故など。法律知識の欠如は、一般的に公立弁護士にしか余裕がなく、真面目な弁護士も「特別な法律を持つ消費者」を避けます。恐れてはいけない「​​ニーズ」。コミュニケーションの主軸:この国のすべての男性、女性、子供は有罪判決を受けるまで無実だと思います。地域:アルバカーキ市スローガン:Thrallに電話したほうがいいです!(ベター・コール・ソール)広告:2つの可能性のある犯罪状況をシミュレートします+サウルの主張+サウルのスローガン2をより適切に呼び出します。

メインネットガイド— Arbitrum Odyssey Week 2

メインネットガイド— Arbitrum Odyssey Week 2

最新のアップデートを受け取るために私たちに従ってください。ニュースレター:https://www。

Language