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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

正規表現

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

Q&A

解決済

3回答

497閲覧

同じパターンの連続のマッチ

NCC1701

総合スコア1680

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

正規表現

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

0グッド

0クリップ

投稿2019/01/31 13:27

前提・実現したいこと

下記のような文字列について、“「」”のみの行が連続している部分を正規表現でマッチさせたいのですが、うまくいきません。

該当のソースコード

python

1import sys, os 2import re 3 4temporary = """ 501: 〓 602: 「」〓 703: 「」〓 804: 「」 905: 「」 1006: 「」〓「」〓 1107: 「」 1208: 〓 1309: 「」 1410: 「」〓 1511: 「」〓「」 1612: 「」 1713: 「」 1814: 「」 1915: 「」「」 2016: 「」〓 2117: 「」 2218: 「」 2319: 〓「」 2420: 「」 25""" 26 27print(temporary) 28match = re.findall(r'(^「」$){2,}', temporary, flags=(re.MULTILINE | re.DOTALL)) 29print(match)

(ヒアドキュメントの部分では説明のため行番号『01:』を入れてあります)

具体例

04と05の連続、12と13と14の連続、17と18の連続で ['「」「」','「」「」「」','「」「」「」']を期待しています。

01のように〓だけのときはマッチしない。02のようにかっこの後に〓があるときはマッチしない。15のように「」が1行で連続しているときはマッチしない。07のように「」が連続しないときはマッチしない。19のように行頭に〓があるときはマッチしない。

試したこと

match = re.findall(r'(「」\n){2,}', temporary, flags=re.DOTALL)
とかも試したけどうまくいきませんでした。

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

python 3.7

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

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

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

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

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

guest

回答3

0

ベストアンサー

正規表現のまま頑張るならこんな感じでしょうか。

Python

1for m in re.findall(r'(?:\n「」){2,}\n', f'\n{temporary}\n'): 2 print(''.join(m.split()))

f'\n{temporary}\n' に対してマッチしているのは、
先頭行あるいは最終行でも漏らさずマッチするための工夫です。

実行結果 Wandbox

「」「」 「」「」「」 「」「」

あるいは

正規表現の利用に拘らないのなら、itertools.groupbyを活用します。

Python

1import itertools 2 3it = itertools.groupby( 4 temporary.splitlines(), lambda l: l == '「」' 5) 6for tf, e in it: 7 if not tf: 8 continue 9 10 e = list(e) 11 if len(e) == 1: 12 continue 13 14 print(''.join(e))

実行結果 Wandbox

「」「」 「」「」「」 「」「」

おまけ。こんなふうに書くと、行数も表示できますね。

Python

1from itertools import groupby, tee 2 3 4def enum_groupby(iterable, condition, *, start=0): 5 num_of_lines = start 6 7 for tf, e1 in groupby(iterable, condition): 8 9 e1, e2 = tee(e1, 2) 10 yield num_of_lines, (tf, e1) 11 12 num_of_lines += sum(1 for _ in e2) 13 14 15it = enum_groupby( 16 filter(None, temporary.splitlines()), lambda l: l == '「」', 17 start=1 18) 19for l, (tf, e) in it: 20 if not tf: 21 continue 22 23 e = list(e) 24 if len(e) == 1: 25 continue 26 27 print(f'{l:2}: {"".join(e)}')

実行結果 Wandbox

4: 「」「」 12: 「」「」「」 17: 「」「」

投稿2019/01/31 13:54

編集2019/01/31 14:21
LouiS0616

総合スコア35660

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

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

0

正規表現に詳しくないのでかなり強引な手段を使っていますが、以下でどうでしょうか

Python

1import re 2temporary = """ 34「」〓 5「」〓 6「」 7「」 8「」〓「」〓 9「」 1011「」 12「」〓 13「」〓「」 14「」 15「」 16「」 17「」「」 18「」〓 19「」 20「」 21〓「」 22「」 23""" 24t =''.join( ['<'+i+'>' for i in temporary.split()]) # 前置、後置文字をつけて1行に連結 25match = re.findall(r'((<「」>){2,})', t) # 一致 26ret = [i[0].replace('<','').replace('>','') for i in match] # 必要な部分のみ抽出 27print(ret) # ['「」「」', '「」「」「」', '「」「」']

投稿2019/01/31 13:57

can110

総合スコア38262

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

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

0

これでどうでしょう。

python

1match = re.findall(r'(?:「」\n){2,}', temporary)

投稿2019/01/31 13:50

KojiDoi

総合スコア13671

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問