web-dev-qa-db-ja.com

正規表現で「この文字シーケンスまでのすべてのもの」とどのように一致させるには?

この正規表現を取りなさい:/^[^abc]/。これは、a、b、またはcを除く、ストリングの先頭にある任意の1文字と一致します。

その後に*を追加した場合 - /^[^abc]*/ - 正規表現は、それがa 、または b 、または cのいずれかを満たすまで、結果に後続の各文字を追加し続けます。

たとえば、ソース文字列が"qwerty qwerty whatever abc hello"の場合、式は"qwerty qwerty wh"まで一致します。

しかし、一致する文字列を"qwerty qwerty whatever "にしたい場合はどうなりますか

...言い換えれば、 正確なシーケンス "abc"までの(しかし含まない)すべてをどのように一致させることができますか?

398
callum

どの種類の正規表現を使用しているかは指定しませんでしたが、これは「完全」と見なすことができる最も一般的な正規表現のいずれでも機能します。

/.+?(?=abc)/

使い方

.+?部分は、.+の欲張りでないバージョンです(1つ以上のもの)。 .+を使うとき、エンジンは基本的にすべてにマッチします。それから、正規表現に何か他のものがあれば、それは次の部分にマッチすることを試みるステップで戻ります。これがgreedyの振る舞いで、できる限り満たすを意味します。

.+?を使用するとき、一度に全部をマッチさせて他の条件(もしあれば)に戻る代わりに、エンジンは正規表現の次の部分がマッチするまで(もしあれば)次の文字を段階的にマッチさせます。これは欲張りでないで、match 満たすことができる最も少ないを意味します。

/.+X/  ~ "abcXabcXabcX"        /.+/  ~ "abcXabcXabcX"
          ^^^^^^^^^^^^                  ^^^^^^^^^^^^

/.+?X/ ~ "abcXabcXabcX"        /.+?/ ~ "abcXabcXabcX"
          ^^^^                          ^

それに続いて、(?={contents}) ゼロ幅アサーション 、a を見回してください 。このグループ化された構造はその内容と一致しますが、一致した文字としてはカウントされません(zero width)。それが一致したか否かに関わらず返されるだけです(assertion)。

したがって、他の用語では、正規表現/.+?(?=abc)/は次のようになります。

"abc"を数えずに、 "abc"が見つかるまで、できるだけ少ない数の文字に一致させます。

785
sidyll

"abc"までのすべてをキャプチャしようとしているのなら、

/^(.*?)abc/

説明:

( )は、$1$2などを使用してアクセスするための括弧内の式をキャプチャします。

^は行の先頭に一致します

.*は何にでもマッチし、?は欲張らずに(必要な最小文字数にマッチ) - [1]

[1]これが必要な理由は、それ以外の場合は次の文字列です。

whatever whatever something abc something abc

デフォルトでは、正規表現は greedy です。これは、可能な限り一致することを意味します。したがって、/^.*abc/は「なんでもabc something」と一致します。欲張りでない量指定子?を追加すると、正規表現は「どんなものであれ」にのみ一致します。

94
Jared Ng

@Jared Ngと@Issunが指摘したように、このようなRegExを解決するための鍵は、「特定のWordまたは部分文字列までのすべてを一致させる」または「特定のWordまたは部分文字列の後のすべてを一致させる」などです。 。 それらについてもっと読む

あなたの特定のケースでは、それは先を見越して解決することができます。絵は千語の価値があります。スクリーンショットの詳細説明を参照してください。

Regex101 Screenshot

34
Devy

必要なのは.+? (?=abc)のようなアサーションを見回すことです。

以下を参照してください。 先読みと先読みゼロ長アサーション

[abc]abcと同じではないことに注意してください。大括弧の中は文字列ではありません - 各文字は可能性の1つにすぎません。大括弧の外側は文字列になります。

8
aevanko

これは正規表現については意味があります。

  1. 正確なWordは、次の正規表現コマンドから取得できます。

( "(。*?)")/ g

ここで、二重引用符の内側に属する正確なWordをグローバルに取得できます。たとえば、検索テキストが

これは「二重引用符」の単語の例です

それから我々はその文から "二重引用符"を得るでしょう。

3

あなたが最後の部分を含めたいのであれば、これはうまくいくでしょう。

.+?(abc)

たとえば、次の行では

I have this very Nice senabctence

"abc"までのすべての文字を選択し、abc も含める

正規表現を使用すると、結果は次のようになります。I have this very Nice senabc

これをテストしてください: https://regex101.com/r/mX51ru/1

3
Dadan

私は私の問題を解決するための助けを探した後、私はこのstackoverflowの質問で終わったが、それに対する解決策は見つかりませんでした:(

だから私は即興でなければなりませんでした...しばらくして私が必要とした正規表現にたどり着くことができました:

enter image description here

ご覧のとおり、最後のダッシュを含めずに、 "grp-bps"フォルダの前に最大1つのフォルダが必要でした。そしてそれは "grp-bps"フォルダの後に少なくとも1つのフォルダを持つことが必要でした。

0
Loaderon

部分式が必要だと思います。私が正しく覚えているならば、あなたは部分式のために通常の()ブラケットを使うことができます。

この部分はgrepマニュアルからです。

 Back References and Subexpressions
       The back-reference \n, where n is a single digit, matches the substring
       previously matched  by  the  nth  parenthesized  subexpression  of  the
       regular expression.

^[^(abc)]のようなことでうまくいくはずです。

0