質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

1745閲覧

正規表現 最初に一致するAまでにBが含まれているか

sasakiyo

総合スコア7

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2020/10/15 01:18

前提・実現したいこと

Pythonで正規表現を使っての文字列の処理を行っています。
ある文章の中から、複数存在する文字列Aと文字列Bを利用して

「文頭から最初にマッチする文字列Aまでに文字列Bが存在するか」

というのを正規表現のパターンとして1行で書くことができません。

text = ''' あーあーあー 本日は晴天なり ただいまマイクのテスト中。 本日は晴天なり ただいまマイクのテスト中。 '''

対象文章が上記text
文字列Aが「本日は晴天なり」
文字列Bが「マイク」
だとした場合

「文頭から最初の本日は晴天なりまでにマイクが存在する」

というチェックしたいということになります。

上記textの場合最初の「本日は晴天なり」までに「マイク」という文字がないので
アンマッチとしたいのですが上手くいきません。
どなたかご教授いただければ幸いです。

補足情報(FW/ツールのバージョンなど)

Python3.8.4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/10/15 01:26

「本日は晴天なり」が全く現れない場合は、どう判定するのが適切でしょうか?
sasakiyo

2020/10/15 01:33

「本日は晴天なり」が全く現れない場合もアンマッチと判定したいです。
maisumakun

2020/10/15 01:35

「正規表現1本で行う」という条件は、何がなんでも変えられないものでしょうか? (他の方法を使ったほうが、より読みやすく実装できると考えられます)
sasakiyo

2020/10/15 01:38

正規表現1本以外だと方法は分かってはいるのですが、正規表現1本の場合実装できるか、という事で今回質問させて頂きました。
yambejp

2020/10/15 05:02

質問がちょっとあいまいです ・すべての行で「本日は晴天なり」の前にマイクがないことを知りたいのか ・全ての行の中で最初の「本日は晴天なり」の前に別の行でもいいのでマイクが1つもないことを知りたいのか 意味が読み取れません
yambejp

2020/10/15 05:04

つまり 「マイク 晴天 ほにゃらら」 はOKなのか? 「晴天 マイク 晴天」 はOKなのか?
sasakiyo

2020/10/15 07:36

質問内容があやふやで申し訳ございませんでした。 ・全ての行の中で最初の「本日は晴天なり」の前に別の行でもいいのでマイクが1つもないことを知りたいのか になります
guest

回答3

0

ベストアンサー

否定先読みを使えばできないでしょうか。

python

1re.match(r'((?!本日は晴天なり).)*マイク.*?本日は晴天なり', text, re.DOTALL)

「マイク」(B)の前に「本日は晴天なり」(A)が存在せず、
「マイク」(B)の後に「本日は晴天なり」(A)があらわれるパターンです。

参考:
https://stackoverflow.com/questions/406230
https://stackoverflow.com/questions/1687620

投稿2020/10/15 02:41

bsdfan

総合スコア4571

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sasakiyo

2020/10/15 07:23

ありがとうございます、こちらで動作が確認できました! 文字列Bを判定する前に文字列Aの判定を入れる所まで思いつきませんでした… ベストアンサーとさせていただきます。
guest

0

  • 「文頭から最初の本日は晴天なりまでにマイクが存在する」ならマッチと判定
  • 「本日は晴天なり」が全く現れない場合はアンマッチと判定

この条件を組み合わせると、

  • 「マイク」の後のどこかに「本日は晴天なり」が現れるときのみマッチ

ということになると思うのですが、これで趣旨はあってるでしょうか。

であれば簡単で、次の正規表現でいいはずです。

マイク.*本日は晴天なり

と思いましたが、コメントでのご指摘が妥当ですね。やはり「言明」を使うしかなさそうです。

投稿2020/10/15 05:22

編集2020/10/15 05:41
KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2020/10/15 05:27

それだと 本日は晴天なりマイク本日は晴天なり がヒットしちゃいませんか?
maisumakun

2020/10/15 05:29

それだと、「本日は晴天なり」が複数回出現する場合に正しく判定できないことが考えられます。
KojiDoi

2020/10/15 05:39

あ、なるほど。
sasakiyo

2020/10/15 07:26

回答ありがとうございます。 自分もそれを試していましたが maisumakun様のご指摘の結果となりました。
guest

0

動作確認してませんが、以下でどうでしょう。

^(?<!.文字列A.)文字列B(?=.文字列A.)$

後読み否定で文字列Bよりも前に文字列Aが存在しないことを、
先読み肯定で文字列Bよりも後に文字列Aが存在することを示します。
ちなみに、文字列Aが存在しない場合も勿論アンマッチとなります。

と思いつきで提案しましたが、
先読み肯定は不要ですね。

投稿2020/10/15 02:44

編集2020/10/15 04:02
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sasakiyo

2020/10/15 07:25

なるほど、と思ったのですが 最初の文字列Aの部分が固定幅にしろというエラーが出てしまいました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問