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

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

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

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

Python

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

Q&A

解決済

2回答

1054閲覧

Python: Regex内で参照はするがマッチさせない

Sigma.KK

総合スコア7

正規表現

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

Python

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

0グッド

0クリップ

投稿2017/12/21 09:26

###前提・実現したいこと
Python2.7でRegexについて勉強中です。

"2003-03-03"や"2011-11-11"のように、西暦の下二桁と月、日が同じものにマッチさせ、取り出したいと思っています。
そこで、下記のコードを試しました。

Python

1import re 2 3pattern = r"\b((?:\d\d)(\d\d)-\2-\2)\b" 4text = """\ 51999-99-11 62017-12-17 72015-10-31 82011-11-11 9""" 10match = re.findall(pattern, text) 11 12if match: 13 print match 14else: 15 print "no match"

このままだと、非現実的な日付にもマッチしてしまいますが、練習なので、わかり易さ重視ということで。

###一応取り出せはしましたが…

[('2011-11-11', '11')]

と、マッチに用いた西暦の下二桁まで出力されてしまいます。
取り出したいのは"2011-11-11"のみです。

###マッチには用いるが、出力はされないようにしたい!
"(?:)"を用いた表現ではRegex内ですら参照できなくなってしまいます。

そこで、名前付きならどうだ!と、"(?P:<year>)"というような表現も試してみたのですがエラーでした。

Regex内では参照するが、出力はされないような表現ってないのでしょうか?

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

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

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

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

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

guest

回答2

0

ちょっと反則っぽいですが、発想の転換という事で。

python

1nn_nn_nn = ('-'.join([str(i) * 2] * 3) 2 for i in range(10)) 3pattern = r"\b(\d\d(?:%s))\b" % '|'.join(nn_nn_nn)

生成されたpatternは、

\b(\d\d(?:00-00-00|11-11-11|22-22-22|33-33-33|44-44-44|55-55-55|66-66-66|77-77-77|88-88-88|99-99-99))\b

となります。

投稿2017/12/21 12:21

YouheiSakurai

総合スコア6142

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

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

Sigma.KK

2017/12/21 12:58

YouheiSakuraiさん、回答ありがとうございます! 私にはパターンをダイナミックに生成するという発想がなかったのでなるほどです。 頂いたコードを多少改変すればマッチは上手くいきそうです! ですが、今回の目標はあくまで勉強で、個人的には「参照はできるが出力はされない表現」ってないだろうか、という点が重要だったんです。 質問文が悪かったです、すみません…! それでもYouheiSakuraiさんの発想はとても参考になります! ありがとうございました!
YouheiSakurai

2017/12/21 13:53

いえいえ、意図は理解してましたがどうにもこうにも無理そうで、最終的には「なんとか正規表現で」という事でこれになりました。お役に立ててれば幸いです。
guest

0

ベストアンサー

出力はされないような表現ってないのでしょうか?

参照を使う場合グルーピングを用いることになるので、おそらくはできない気がします。Pythonなのでそのようなこった正規表現を考えるよりは

match = [m[0] for m in re.findall(pattern, text)]

ぐらいで満足してはいかがでしょうか?


追記:もっとよい方法のコメントをいただきました。

matches = [m.group(1) for m in re.finditer(pattern, text)]

findallを用いると個々の要素はfindallが決めた内容になってしまいますが、finditerを用いると個々の一致部分についてのmatchオブジェクトを得られます。このようにした方が結果をより柔軟に加工できそうです。

コメントありがとうございます>yubaさん

投稿2017/12/21 10:47

編集2017/12/22 05:20
KSwordOfHaste

総合スコア18394

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

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

Sigma.KK

2017/12/21 12:16

やっぱりそうなのでしょうか… あくまでRegexの勉強だったのでRegexオンリーで頑張ってみたかったのです…! 先後読みなどを駆使すればどうにかならないかなと色々試してみたのですがダメでした。 諦めることにします…無念です…! ありがとうございました!!
KSwordOfHaste

2017/12/21 12:34 編集

> Regexの勉強だったのでRegexオンリーで頑張ってみたかった 「その態度は大切」だと自分は思います。自分のコメントは「まずは可能な方法を」というものですが、それはそれとして、正規表現の様々な可能性について調べるのは(例え最終的にできないことが分かったとしても)無駄ではないと思います。調べているうちに別の点で新たな知識を得るなんてこともよくありますよね。 ただどこまででキリを付けて別の方法を考えるかはなかなかに難しい判断だと思います。自分の場合「あくまで勘だけど、なんかできそうな気がする」という根拠で粘る場合もありますし、逆に「どうもこれはできないのが正しそう」という予想で早々にあきらめる場合もあります。その正解率がどうなのかは自分で判断するのは難しいですが、そのようなときこそ本サイトのような場で閲覧者のみなさんの判断・アドバイスを得るのが有効だと思います。こうしたサイトのよい点は回答者が一人ではないことだと思います。例えば上の回答が不正解だった場合でも他の方から指摘をいただける場合がありますし!
KSwordOfHaste

2017/12/21 12:37

そういっているうちにYouheiSakuraiさんが別の発想のコメントをくださいましたよ! こういう点が本サイトの嬉しいところなんじゃないかなぁと自分は思います。
yuba

2017/12/21 23:49

質問文の通りのパターンで単に print(match.group(0)) とすれば取り出せたのではないですか?
KSwordOfHaste

2017/12/22 00:52

finditerで個々のMatchを取り出してgroupなどで興味のある部分を取り出す以下のようなパターンということですよね・・・ [m.group(1) for m in re.finditer(pattern, text)] こちらのほうが、より分かり易く応用がききそうに感じます。
yuba

2017/12/22 02:53

そうそう、そういうことです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問