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

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

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

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

Q&A

解決済

2回答

442閲覧

re.sub()がうまくいかない

Avent

総合スコア47

Python 3.x

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

0グッド

1クリップ

投稿2022/09/22 20:50

前提

正規表現での置換がうまくできません。

実現したいこと

拡張子を置き換える

該当のソースコード

Python

1import re 2 3name = 'hoge.jpg' 4print(re.sub(r'[^.]*$', 'webp', name))

出力

hoge.webpwebp

正規表現を変えると上手く行ったのですが、なぜこの正規表現パターンでうまくいかないのかを教えてください。

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

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

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

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

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

y_waiwai

2022/09/22 22:45

うまくいかないとは、どういうふうになるんでしょうか
Avent

2022/09/22 23:36

出力から分かる通り jpg が webpwebp と、二重に置き換えられてしまいます。
guest

回答2

0

ベストアンサー

re.sub(pattern, repl, string, count=0, flags=0)

The optional argument count is the maximum number of pattern occurrences to be replaced; count must be a non-negative integer. If omitted or zero, all occurrences will be replaced. Empty matches for the pattern are replaced only when not adjacent to a previous empty match, so sub('x*', '-', 'abxd') returns '-a-b--d-'.

Changed in version 3.7: Empty matches for the pattern are replaced when adjacent to a previous non-empty match.

python

1>>> import sys 2>>> sys.version 3'3.10.6 (main, Aug 10 2022, 11:40:04) [GCC 11.3.0]' 4 5>>> import re 6>>> name = 'hoge.jpg' 7>>> print(re.sub(r'[^.]*$', 'webp', name, count=1)) 8hoge.webp

投稿2022/09/23 02:37

melian

総合スコア19803

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

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

0

ドットの次で一致して webpが挿入され、挿入された文字列で再び webp が挿入されているようですね。
正規表現を [^.]+$ にすれば1回置換されるだけで済みます。
ただし、ファイルの先頭がドットで始まる場合もあるので、os.path.splitextやpathlib.Path を使った方がいいと思います。

py

1import re 2import os 3import pathlib 4 5name = 'hoge.jpg' 6print(re.sub('[^.]+$', 'webp', name)); 7print(os.path.splitext(name)[0] + '.webp') 8print(pathlib.Path(name).stem + '.webp') 9 10name = '.profile' 11print(re.sub('[^.]+$', 'webp', name)); 12print(os.path.splitext(name)[0] + '.webp') 13print(pathlib.Path(name).stem + '.webp')

text:実行結果

1hoge.webp 2hoge.webp 3hoge.webp 4.webp 5.profile.webp 6.profile.webp

投稿2022/09/22 23:31

編集2022/09/22 23:59
shiracamus

総合スコア5406

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

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

Avent

2022/09/22 23:35 編集

質問の最後に書いたつもりだったのですが、質問の書き方がわかりにくかった場合は申し訳ありません。 その方法はすでに思いついており意図した結果は得ることができたのですが、どうして `r'[^.]*$'` では上手くいかないのが知りたいです。
shiracamus

2022/09/22 23:54 編集

回答を修正しました。
shiracamus

2022/09/23 00:04 編集

javascript で試してみたところ、一度の置換で済んでいますね。 Pythonの動作がおかしい気がします。 > 'hoge.jpg'.replace(/[^.]*$/, 'webp') 'hoge.webp'
quickquip

2022/09/23 01:43 編集

JavaScriptだとフラグg付きの正規表現がPythonのsub(count=0)呼び出しに相当します。 JavaScriptでも同じ動作です。 > 'hoge.jpg'.replace(/[^.]*$/g, 'webp') 'hoge.webpwebp'
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問