正規表現で「この文字シーケンスまでのもの」に一致させる方法は?


515

次の正規表現を見てください/^[^abc]/。これは、a、b、cを除く、文字列の先頭にある任意の1文字と一致します。

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

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

しかし、一致する文字列にしたい場合 "qwerty qwerty whatever "

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


どういう意味match but not includingですか?
Toto

5
"qwerty qwerty whatever "「abc」を含めずに一致させたいのです。つまり、結果の一致がになりたくありません"qwerty qwerty whatever abc"
カラム

2
JavaScriptでは、次のことができますdo string.split('abc')[0]。確かにこの問題に対する公式の回答ではありませんが、正規表現よりも簡単だと思います。
ウィリアムジャッド

回答:


1022

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

/.+?(?=abc)/

使い方

.+? 部分はの非欲張りバージョンです .+ (何の一つ以上)。を使用する.+と、エンジンは基本的にすべてに一致します。次に、正規表現に他に何かがある場合、次の部分を一致させようとする手順に戻ります。これは 貪欲な行動であり、可能な限り満足することを意味ます。

を使用すると .+?、一度にすべてを照合して他の条件(存在する場合)に戻る代わりに、正規表現の後続部分が一致するまで(存在する場合)、エンジンは次の文字を段階的に照合します。これは貪欲はありません。つまり、満足できる限り少ない数に一致 ます。

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

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

続いて 、 ゼロ幅のアサーション見回しがあり ます。このグループ化された構造はその内容と一致しますが、一致した文字(ゼロ幅)としてはカウントされません。一致するかどうかだけが返されます(アサーション)。(?={contents})

したがって、別の言い方をすると、正規表現/.+?(?=abc)/は次のことを意味します。

「abc」を数えることなく、「abc」が見つかるまで、できるだけ少ない文字に一致させます。


12
キャプチャされることになっている場合、これはおそらく改行では機能しません。
einord

3
違いは何だ.+?とは.*
ロビー2017

4
@ robbie0630 +は1以上を*意味し、0以上を意味します。の包含/除外は、?貪欲または非貪欲にします。
jinglesthula 2017

2
@ testerjoe2 /.+?(?=abc|xyz)/
JohnWrensby

4
探しているパターンが存在しない場合は何も選択できないことに気づきました。代わりに^(?:(?!abc)(?!def).)*チェーンを使用して不要なパターンを除外でき、パターンが存在しない場合でも必要に応じてすべてを取得します
カランシシュー

122

「abc」までのすべてをキャプチャする場合:

/^(.*?)abc/

説明:

( )使用したアクセスのための括弧内の式を取り込む$1$2など、

^ 行頭に一致

.*?欲張らずに何にでも一致(必要な最小文字数に一致)-[1]

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

whatever whatever something abc something abc

デフォルトでは、正規表現は貪欲です。つまり、可能な限り一致します。したがって、/^.*abc/「何か、何でも、何でも」と一致します。非貪欲な量指定子?を追加すると、正規表現は「何かにかかわらず」とのみ一致します。


4
ありがとう、しかしあなたの1つ試合にabcを含みます。言い換えれば、結果として生じる一致は、「なんでもabcなんでも」です。
カラム

1
最終的に何をしようとしているのか説明してもらえますか?シナリオが次の場合:(A) "abc"までのすべてを取得したい-キャプチャしたいものを括弧で囲んでください。(B)「abc」までの文字列に一致させたい-とにかくabcをチェックする必要があるため、関係なく正規表現の一部である必要があります。それがそこにあることを他にどのように確認できますか?
Jared Ng

sedは貪欲でないマッチングをサポートしていないようで、ルックアラウンド((?=...))もサポートしていません。他に何ができますか?コマンド例:をecho "ONE: two,three, FOUR FIVE, six,seven" | sed -n -r "s/^ONE: (.+?), .*/\1/p"返しますがtwo,three, FOUR FIVE、期待していtwo,threeます...
CodeManX

1
@CoDEmanX特にsedに関するものであるため、コメントではなく独自の質問として投稿する必要があります。そうは言っても、あなたの質問に対処するために、あなたはこの質問への答えを見たいかもしれません。また、この例では、貪欲twoでないインタプリタはでなくだけを返すことに注意してくださいtwo,three
Jared Ng

3
これはどのようにあるEVERY正規表現の答えがなければならない例と-見て、すべてのパーツの説明を ...
jave.web

54

@Jared Ngと@Issunが指摘したように、「特定の単語または部分文字列まですべてを一致させる」または「特定の単語または部分文字列の後のすべてを一致させる」のようなこの種のRegExを解決するための鍵は、長さゼロのアサーションと呼ばれます。それらの詳細については、こちらをご覧ください。

あなたの特定のケースでは、前向きな前向きな見方で解決できます: .+?(?=abc)

写真は千の言葉の価値があります。スクリーンショットの詳細な説明を参照してください。

Regex101スクリーンショット


23
.+?(?=abc)コピー貼り付け可能な正規表現はもっと価値があります。
トム

先頭のスペースを除外するのはどうですか?
Royi


7

Javaの正規表現の場合、およびほとんどの正規表現エンジンも信じていますが、最後の部分を含めたい場合は、これでうまくいきます。

.+?(abc)

たとえば、次の行では:

I have this very nice senabctence

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

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

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


4

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

だから即興しなければならなかった...しばらくして、必要な正規表現にたどり着くことができた。

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

ご覧のとおり、最後のダッシュを含めずに、「grp-bps」フォルダの前に最大1つのフォルダが必要でした。また、「grp-bps」フォルダの後に少なくとも1つのフォルダが必要でした。

編集する

コピーして貼り付けるテキストバージョン(テキストの「grp-bps」を変更):

.*\/grp-bps\/[^\/]+

6
テキスト版はありませんか?🙄
kiradotee

2

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

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

( "(。*?)")/ g

ここでは、二重引用符で囲まれた正確な単語をグローバルに取得できます。たとえば、検索テキストが

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

次に、その文から「二重引用符」が付けられます。


StackOverflowへようこそ。ご協力いただきありがとうございます。しかし、これが質問で述べられた目標にどのように役立つかを理解するのは難しいと思います。詳しく説明できますか?与えられた例にそれを適用できますか?あなたはの処理に焦点を当てているようですが"、私にはそれは質問には無関係のようです。
ユンノシュ

1
こんにちは、私は特殊文字の間に単語や文を入れる方法を説明しました。ここでも私たちの質問は「特殊文字のシーケンスまで何でも」です。二重引用符で試して、ここで説明しました。ありがとう。
ポンムルガンモハンラージ2017年

2

Pythonの場合:

.+?(?=abc) 単一行のケースで機能します。

[^]+?(?=abc)Pythonは[^]を有効な正規表現として認識しないため、機能しません。複数行のマッチングを機能させるには、re.DOTALLオプションを使用する必要があります。次に例を示します。

re.findall('.+?(?=abc)', data, re.DOTALL)

0

部分式が必要だと思います。私の記憶が正しければ()、部分式に通常の角かっこを使用できます。

この部分は、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)]トリックを行う必要があるような何かを行います。


すみません、それはうまくいきません。abcを括弧で囲んでも違いはないようです。それらは依然として「a OR b OR c」として扱われます。
カラム

-1

$マーク文字列の最後なので、このような何か作業をする必要があります:[[^abc]*]$あなたは、任意の反復で終わらないものを探しているabcが、それは終わりでなければならないであろう

また、正規表現でスクリプト言語を使用している場合(phpやjsなど)、パターンに最初に遭遇したときに停止する検索機能があります(左から開始するか、右から開始するか、phpを使用して、文字列をミラー化するために内破を行うことができます)。


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