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

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

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

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

正規表現

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

Q&A

解決済

5回答

1496閲覧

正規表現のreplaceの右から回数制限について

skane

総合スコア25

Python 3.x

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

正規表現

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

2グッド

1クリップ

投稿2020/03/13 07:29

編集2020/03/15 23:58

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
(例)PHP(CakePHP)で●●なシステムを作っています。
■■な機能を実装中に以下のエラーメッセージが発生しました。

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

正規表現のreplaceについて行き詰っています。 例えば、「abccbdaba」と合ったとき、2つ目の"b"のみをxに書き換えたいとします。 以下のようなソースコードで実行していますが、できません。 左から回数制限を実施するものは調べると出てきますが、右からはなく試してみましたができませんでした。 ご知見をいただければと思います。

該当のソースコード

text = "abccbdaba" text2 = text.replace(b,x)

試したこと

text2 = text.replace(b,x,-1)
にすると、右からになるかな?と淡い期待を持ちましたが、ダメでした。。

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

皆様、回答いただきありがとうございます。

実際に必要だった条件が、右から数えて一つ目のb(文字列)のみを書き換えたいというものでした。
なので、反転して文字列の前から探す手法をとりました。

text = "abccbdaba" #abcdはそれぞれ文字列

text_r = "".join(list(reversed(text)))
b_r = "".join(list(reversed(b)))
x_r = "".join(list(reversed(x)))
text_rr = text_r.replace(b_r,x_r,1)
text_new = "".join(list(reversed(textrr)))
print(text_new)

計算コストがややかかりすぎている印象で、いただいたご知見を活かさせていただきたいと思います。

DrqYuto, s.k👍を押しています

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

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

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

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

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

guest

回答5

0

むりやり
replace()の第3引数の21をうまく指定すると2~4つ目とか範囲指定できたりします。

左から2つ目のbxに。

Python

1>>> "abccbdaba".replace('b','x',2).replace('x','b',1) 2'abccxdaba' 3>>> "abccbbdaba".replace('b','x',2).replace('x','b',1) 4'abccxbdaba'

右から2つ目のbxに。

Python

1>>> "abccbdaba"[::-1].replace('b','x',2).replace('x','b',1)[::-1] 2'abccxdaba' 3>>> "abccbbdaba"[::-1].replace('b','x',2).replace('x','b',1)[::-1] 4'abccbxdaba'

投稿2020/03/13 09:18

編集2020/03/13 09:24
Y.H.

総合スコア7914

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

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

skane

2020/03/15 23:38

ご回答が遅くなり、申し訳ありません。 ご回答ありがとうございます。 なるほどです。 一度変換した後に、もう一度戻す方法ですね。
guest

0

一旦分解して組み直すのがわかりやすい気がします。

import re # 文字列xの右からn番目の文字列rを文字列sに置き換える。 def myreplace(x, n, r, s): r = "("+r+")" xx = re.split(r, x) xx[-n*2] = s return("".join(xx)) txt = "abccbdaba" r = myreplace(txt, 2, "b", "z") print(r)

投稿2020/03/13 08:49

KojiDoi

総合スコア13671

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

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

skane

2020/03/15 23:36

返信が遅くなり、申し訳ありません。 ご回答いただきありがとうございます。 splitで分ける方法ですね。 関数化する方いいですね。pythonで作成することを考えてませんでした。 ありがとうございます。
guest

0

ベストアンサー

余り美しくはない方法です。
re.finditerでマッチ文字位置を取得して文字スライスで挿入する方法です。
より美しいやり方をご存じの方がいましたらお願いします。

python

1import re 2 3text = "abccbdaba" 4#finditerで全てのマッチ文字の位置を取得 5mi = [m.span() for m in re.finditer('b', text)] 6#位置で元文字をスライスして間に文字を挿入する(例:二つ目のbをzに置換) 7rtext = text[:mi[1][0]] + 'z' + text[mi[1][1]:] 8print(rtext)

追記
何回もすいません。
正規表現オンリーの方法もありました。

python

1import re 2 3text = "abccbdaba" 4text = re.sub('([^b]*b[^b]*)b([^b]*)', '\1z\2', text) 5print(text)

b以外と言う表現を使って何回目か割り出す方法ですね。

投稿2020/03/13 08:26

編集2020/03/13 09:19
yureighost

総合スコア2183

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

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

skane

2020/03/15 23:26

ご回答が遅くなり、申し訳ありません。 ご回答ありがとうございます。 追記方法は、末尾から数えられていますか? 十分に理解できず、すみませんが、先頭から2個目に対応しているような気がして。。 よろしくお願いします。
guest

0

pythonには詳しくないのですが正規表現の置換はsubでは?

正規表現でベタに後ろから2番目のbをxに返るとすると
「b([^b]?b[^b]$」を"x$1"に変えたりする感じですかね

投稿2020/03/13 07:54

yambejp

総合スコア114839

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

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

skane

2020/03/13 08:04

ご回答ありがとうございます。 ご指摘通り、正規表現の置換はre.subです。 しかし、これを使うと回数制限すらできなかったので、replaceに移行した経緯があります。 bの個数に決まりがないため、書き方には注意が必要ですが、無難にその方法でしょうか。
otn

2020/03/13 14:12

閉じ括弧が漏れてますね。 re.sub("b([^b]*b[^b]*)$",r"x\1",text)
guest

0

皆様、回答いただきありがとうございます。

実際に必要だった条件が、右から数えて一つ目のb(文字列)のみを書き換えたいというものでした。
なので、反転して文字列の前から探す手法をとりました。

text = "abccbdaba" #abcdはそれぞれ文字列

text_r = "".join(list(reversed(text)))
b_r = "".join(list(reversed(b)))
x_r = "".join(list(reversed(x)))
text_rr = text_r.replace(b_r,x_r,1)
text_new = "".join(list(reversed(textrr)))
print(text_new)

計算コストがややかかりすぎている印象で、いただいたご知見を活かさせていただきたいと思います。

投稿2020/03/15 23:56

skane

総合スコア25

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問