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

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

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

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

Python

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

Q&A

解決済

1回答

591閲覧

正規表現の文字置換についてー2

muryayan

総合スコア7

正規表現

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

Python

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

0グッド

0クリップ

投稿2021/09/07 06:05

前提・実現したいこと

正規表現で文字列の置換を試しているのですが、「両端が空白」「先頭で後ろは空白」「先頭が空白で末尾」の3種類で色々な文字列を空白と置換しようとしています。

発生している問題・エラーメッセージ

'i like i ab ib cd an a 20 2b cd-30 30-cd 5 modeling modeling-i, 2020 and 1-modeling modeling j'という意味のない文章から、以下のコードで置換を試みています。 数字の置換、1文字の置換、deleteにある文字列の置換は期待した通りの置換が行えていますが、2文字の置換が上手く行えていません。 ab, cd, 20は置換して消えていますが、ib, anが置換していません。 どうすれば、ib, anも空白と置換できるでしょうか?

該当のソースコード

Python

1#入力 2delete = 'model|modeling' 3text = 'i like i ab ib cd an a 20 2b cd-30 30-cd 5 modeling modeling-i, 2020 and 1-modeling modeling j' 4 5text = re.sub(r'\s[0-9]+\s', ' ', text) #両方空白の数字削除 6text = re.sub(r'\s[0-9]+$', ' ', text) #先頭空白、末尾の数字置換 7text = re.sub(r'^[0-9]+\s', ' ', text) #先頭、末尾空白の数字置換 8 9text = re.sub(r'\s\S\s', ' ', text) #両方空白の1文字置換 10text = re.sub(r'\s\S$', ' ', text) #先頭空白、末尾の1文字置換 11text = re.sub(r'^\S\s', ' ', text) #先頭、末尾空白の1文字置換 12 13text = re.sub(r'\s\S\S\s', ' ', text) #両方空白の2文字削除 14text = re.sub(r'\s\S\S$', ' ', text) #先頭空白、末尾の2文字置換 15text = re.sub(r'^\S\S\s', ' ', text) #先頭、末尾空白の2文字置換 16 17text = re.sub(r'\s('+delete+')\s', ' ', text) #両方空白の文字列置換 18text = re.sub(r'\s('+delete+')$', ' ', text) #先頭空白、末尾の文字列置換 19text = re.sub(r'^('+delete+')\s', ' ', text) #先頭、末尾空白の文字列置換 20 21print (text) 22 23#実際の出力 24like ib an cd-30 30-cd modeling-i, and 1-modeling 25 26#期待していた出力 27like cd-30 30-cd modeling-i, and 1-modeling

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

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

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

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

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

itagagaki

2021/09/07 06:50

print (text) を置換のたびに置いて、textの内容の移り変わりを確かめてみては?
muryayan

2021/09/07 07:05

ありがとうございます。 全てのステップを確認してみましたが、ab, cd, 20が置換するタイミングで、ib, anが置換していません。
itagagaki

2021/09/07 07:24

なぜそれが正規表現パターンにマッチしないのか考えてみてください。 (回答にヒントが出ていますね)
guest

回答1

0

ベストアンサー

カーソルを意識しましょう。

python

1re.sub(r'\s\S\S\s', ' ', " ab cd ")

を実行してみてください。

" ab cd " -> " ab " + "cd " -> " " + "cd "

となり、置換後は c の位置から探し始めてしまいます。

これを回避するには先読みなどを使う方法が考えられます。

投稿2021/09/07 07:05

mather

総合スコア6753

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

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

muryayan

2021/09/07 07:25

ありがとうございます。カーソルを意識するというのは分かりやすかったです。 ただ、先読みは色々見てみましたが、どうすればこれを解決できるのかが分かりませんでした。 とりあえず、2回繰り返せば、解決できましたが、スマートではありませんね。 #入力 text1 = re.sub(r'\s\S\S\s', ' ', " ab cd ") text2 = re.sub(r'\s\S\S\s', ' ', text1) print ("text1: "+text1) print ("text2: "+text2) #出力 text1: cd text2:
mather

2021/09/07 07:33

「正規表現 先読み」などで検索してみましたか?様々な解説が載っていると思います。 わからない、というときはちょっと立ち止まって「自分は一体どこまで理解できていて何がわからないのだろうか」と自問自答することが大事です。 先読みの使い方としては次のようになります。 re.sub(r'\s\S\S(?=\s)', '', " ab cd ") 「先を読むけど、カーソルは移動させない」ということですね。 置換後の文字列が半角スペースではなく空文字になっている部分もポイントです。 なぜ動くのか、" ab cd " 以外にも色々なサンプルを使って考えてみてください。
muryayan

2021/09/07 07:46

ありがとうございました。 先読みは「先を読むけど、カーソルは移動させない」ということなのですね。 先読みについて理解を深めるため、他の解説も読み、色々試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問