web-dev-qa-db-ja.com

(this | string)ではなく、一致ではなく除外する正規表現をどのように記述しますか?

グループを除外するEmacs正規表現を作成しようとして困惑しています。 _[^]_はセット内の個々の文字を除外しますが、特定の文字sequencesを除外したい:[^(not|this)]のようなもので、 "not"または "this"を含む文字列一致しません。

原則として、私は_([^n][^o][^t]|[^...])_を書くことができますが、よりクリーンな別の方法はありますか?

27
Anycorn

まず第一に: [^n][^o][^t]は解決策ではありません。これにより、nil[^n]は一致しません)、bob[^o]が一致しない)またはcat[^t] 一致していません)。

ただし、notthisも含まない文字列に一致する基本的な構文で正規表現を作成することは可能です。

^([^nt]|n($|[^o]|o($|[^t]))|t($|[^h]|h($|[^i]|i($|[^s]))))*$

この正規表現のパターンは、単語の最初の文字ではない、または単語のプレフィックスのみで、単語全体ではない文字を許可することです。

16
Gumbo

これは簡単には不可能です。正規表現はmatchに一致するように設計されており、これが実行できるすべてです。

まず、_[^]_は「除外グループ」を指定せず、否定された文字クラスを指定します。文字クラスは、どのような形や形でもグループ化をサポートしていません。これらは単一の文字(および便宜上、文字範囲)をサポートします。正規表現エンジンに関する限り、[^(not|this)][^)(|hinots]と100%等価です。

この状況から抜け出すには、3つの方法があります。

  1. 一致する_(not|this)_およびexclude現在の環境の助けを借りて一致する(一致結果を否定する)
  2. 正規表現エンジンでサポートされていて、その状況で実現可能な場合は、否定先読みを使用します
  3. matchのように式を書き直します (以前に私が尋ねた同様の質問)を参照
24
Tomalak

(ガンボから)受け入れられた回答が実際に受け入れられたとは信じられません! できないがあなたが望むことをすることを示しているのでそれが受け入れられない限り。このような正規表現を生成する関数がない場合(Gumboが示すように)、それらを作成するのは本当に大変です。

実際のユースケースは何ですか?本当に何をしようとしていますか?

Tomalakが示したように、(a)これは正規表現が行うことではありません。 (b)問題について何をすべきかを含め、適切な説明については、彼がリンクしている他の投稿を参照してください。

答えは、正規表現を使用してnotと一致するように一致させ、それを初期ドメインから減算することです。 IOW、正規表現に除外を行わせないでください(できない)。除外したいものと一致するように正規表現を使用して除外afterを実行します。

これは、正規表現を使用するすべてのツールが機能する方法です(例:grep):減算する必要があるものと一致した後、減算を実行する個別のオプション(例:構文)を提供します。

13
Drew

否定的な先読みを試みているようです。つまり、区切り文字に到達すると、マッチングを停止しようとしています。

Emacsは先読みを直接サポートしていませんが、*、+ 、?の貪欲でないバージョンをサポートしています。演算子(*?、+?、??)。ほとんどの場合、同じ目的で使用できます。

たとえば、このJavaScript関数の本体と一致させるには、次のようにします。

bar = function (args) {
    if (blah) {
        foo();
    }
};

次のemacs正規表現を使用できます。

function ([^)]+) {[[:ascii:]]+?};

ここで、2つの要素シーケンス「};」が見つかったら停止します。 [[:ascii:]]は「。」の代わりに使用されます。複数行にわたって機能するため、演算子。

};なので、これは否定先読みとは少し異なります。シーケンス自体は一致しましたが、その時点までのすべてを抽出することが目的である場合は、キャプチャグループ\(および\)を使用するだけです。

Emacs regexマニュアルを参照してください: http://www.gnu.org/software/emacs/manual/html_node/emacs/Regexps.html

補足として、あらゆる種類のemacs regexを作成する場合は、必ずM-x re-builderを呼び出してください。これにより、現在のバッファーに対して正規表現を書き込むための小さなIDEが表示されます。

9
catphive

M-xフラッシュラインを試してください。

6
offby1

論理テストのために文字列を照合するユースケースでは、これを行います:

;; Code to match string ends with '-region' but excludes those that has 'mouse'.
M-x ielm RET
*** Welcome to IELM ***  Type (describe-mode) for help.
ELISP> (setq str1 "mouse-drag-region" str2 "mou-drag-region" str3 "mou-region-drag")
"mou-region-drag"
ELISP> (and (string-match-p "-region$" str1) (not (string-match-p "mouse" str1)))
nil
ELISP> (and (string-match-p "-region$" str2) (not (string-match-p "mouse" str2))) 
t
ELISP> (and (string-match-p "-region$" str3) (not (string-match-p "mouse" str3)))
nil

私はこのアプローチを使用して、先ほど説明した関数のバグを回避します Over Here

2
biocyberman