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

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

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

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

正規表現

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

Q&A

解決済

3回答

1390閲覧

Python3で正規表現を用いて抜き出した文字列に操作を加えた後に書き換える。

Danrussia

総合スコア44

Python 3.x

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

正規表現

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

0グッド

0クリップ

投稿2020/03/02 07:57

前提・実現したいこと

Python3で正規表現を使用して以下の事を実装したいです。

1.正規表現で文字列(下の"正規表現を使用する文字列")から特定の数字列を取り出し、数字列に1を足した後に、str型にする。 #特定の数字列: .jpg以下の1~3桁の数字 2. re.search()を使用して正規表現で抜き出した特定の数字列のindexを把握する ★ 3. (1.)のものを(2.)で得られたindexに代入する

1番と3番に関しては実装できるのですが、2番が実装できません。

正規表現を使用する文字列

Re_a_img063c.jpg_1.csv Re_a_img063c.jpg_21.csv Re_a_img063c.jpg_100.csv Re_b_img065c.jpg_3.csv

#操作後に得たい文字列

操作前:Re_a_img063c.jpg_1.csv 操作後:Re_a_img063c.jpg_2.csv 操作前:Re_a_img063c.jpg_21.csv 操作後:Re_a_img063c.jpg_22.csv 操作前:Re_a_img063c.jpg_99.csv 操作後:Re_a_img063c.jpg_100.csv 操作前:Re_b_img065c.jpg_3.csv 操作後:Re_b_img065c.jpg_4.csv 操作前:Re_b_img065c.jpg_40.csv 操作後:Re_b_img065c.jpg_41.csv

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

re.search()関数を使用してインデックスを入手しようとしたのですが、特定の数字列の部分を上手く得ることができません

import re string = "Re_a_img063c.jpg_1.csv" matchObj = re.search(r'Re_[a-zA-Z]{1,3}_img\d{0,3}c.jpg_(\d{0,3}).csv', string) if matchObj: print(matchObj.group()) # マッチした文字列: Re_a_img063c.jpg_1.csv print(matchObj.start())# マッチした文字列の開始位置: 0 print(matchObj.end()) # マッチした文字列の終了位置: 22 print(matchObj.span()) # マッチした文字列の開始位置と終了位置: (0,22)

該当のソースコード

Python3

1import re 2string = "Re_a_img063c.jpg_1.csv" 3m = re.fullmatch(r'Re_[a-zA-Z]{1,3}_img\d{0,3}c.jpg_(\d{0,3}).csv',string) 4m.group(1) 5gottenNumber=m.group(1) 6addedNumber = str(int(a)+1) 7# "2"

###試した事
以下の様なサイトを真似てみたのですが、上手くできませんでした。
https://note.nkmk.me/python-str-search/
https://uxmilk.jp/8683

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

直接的な解決案の回答でなくとも、参考になりそうなサイト、類似の事例を教えて頂けると幸いです。
お忙しいとは思いますが、よろしくお願いいたします。
情報に不足がありましたら、ご指摘お願いいたします

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

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

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

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

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

guest

回答3

0

re.subが置換処理に特化しています。

Python

1>>> def replace(m): 2... return m.group(1) + str( 3... int(m.group(2)) + 1 4... ) 5... 6>>> re.sub(r'(abc)(\d+)', replace, 'abc123') 7'abc124'

re.sub — Python 3.8.2 ドキュメント

投稿2020/03/02 08:05

LouiS0616

総合スコア35668

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

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

Danrussia

2020/03/02 08:44

先ほどから、素早い回答ありがとうございます。re.subに関しては知らなかったので助かりました。 後学のために何点かお聞きしたい所があるのですが、 ・re.subの公式ドキュメントを読み解けなかったので、他の解説されているサイトでre.subを調べてみたのですが、第二引数に関しては"置換先文字列"という扱いでした。回答して頂いたコードでは引数なしで ダイレクトに関数名を入れていますが、これでなぜ動作するのでしょうか? (見たサイト:https://note.nkmk.me/python-str-replace-translate-re-sub/) ・replace()という関数を制定されている中で、中にm.group(1),m.grouo(2)という書き方についてんなのですが、公式ドキュメント(https://docs.python.org/ja/3/library/re.html#re.Match.group)内での .group()には 「マッチした文字列を取得する、もともとの文字列が存在する」というようなニュアンスで読みとりました。ですが、関数内にベースとなる文字列は見当たらない中で、関数内の.group()はどのような働きをしていますか? 乱文になってしまいましたが、もしお時間がある時に教えて頂ければ幸いです。 コードに関しては以下の様な形で動作しました。 import re def replace(m): return m.group(1) + str(int(m.group(2)) + 1) re.sub(r'(Re_[a-zA-Z]{1,3}_img\d{0,3}c.jpg_)(\d{0,3})(.csv)', replace, 'Re_a_img063c.jpg_1.csv')
LouiS0616

2020/03/02 08:53 編集

> 回答して頂いたコードでは ~ これでなぜ動作するのでしょうか? re.subの第二引数には二通りあります。 ・置換文字列 ・置換文字列を生成する為の、関数オブジェクト (マッチリザルトを引数に取り、文字列を返すのであれば実装は何でも良い) replaceは後者として使っています。 やや煩雑になる為避けましたが、ラムダ式を用いることも多いです。 --- > group()には ~ 関数内の.group()はどのような働きをしていますか? 関数はマッチした結果を引数に取っています。print(type(m), m) とかしてみると分かるかと。 先の質問のキャプチャを利用し、文字部分と数字部分をそれぞれ取り出しています。 --- > コードに関しては以下の様な形で動作しました。 私はヒントを書いただけですから、ほとんど自力で書いたと言えるでしょう。 こういう経験が積み重なると自信に繋がっていくかと思います。
Danrussia

2020/03/02 09:06

回答ありがとうございます。正規表現?計算機科学?の部分の見識が殆どないので、Louisさんの回答を自分が他人に教える事ができる位に理解は深められていないのですが、ひとまずは内側の動作が分かってよかったです。漠然とした質問に答えて頂きありがとうございました。また今後、何かの機会で質問する事があったらよろしくお願いいたします。
guest

0

ベストアンサー

こんにちは

以下でどうでしょう?

python3

1re.sub(r'(?<=_)([0-9]+)(?=.csv$)', lambda m: f'{1+int(m.group(1))}', 'Re_a_img063c.jpg_1.csv') # => Re_a_img063c.jpg_2.csv

追記

re.sub を使わない、別の方法を挙げます。

python3

1ls = re.split(r'([_.])', 'Re_a_img063c.jpg_99.csv')

とすると、 ls は以下のような内容のリストになります。

['Re', '_', 'a', '_', 'img063c', '.', 'jpg', '_', '99', '.', 'csv']

上記のリストの、末尾から数えて3個目の要素'99'を数値に変換して 1 を加え、再度、文字列に戻してから、すべての要素を連結した文字列にすれば、Re_a_img063c.jpg_100.csv が得られます。

以下は、この考え方によるサンプルです。

投稿2020/03/02 08:43

編集2020/03/02 10:42
jun68ykt

総合スコア9058

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

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

Danrussia

2020/03/02 08:49

回答ありがとうございます。正規表現の操作に慣れていないのと、lamda式の読解が苦手なのでコードの把握に少し時間がかかりますが、把握した後にまたご返信します。
jun68ykt

2020/03/02 10:10

どういたしまして。いろいろ詰め込みました。具体的には以下を使っています。 - (?<=_):正規表現の肯定後読み - (?=.csv$):正規表現の肯定先読み - subの第2引数に、lambdaを使用 - lambda が返す文字列を作るところで、 f文字列 f'{・・・}' を使用
Danrussia

2020/03/02 12:39

返信が遅くなってしまい申し訳ありません。ちょっと他の用事が立て込んでいました。 正規表現,Lamda式の意味は自分の調べたものと相違がなかったです。 追記の実装ですが、正規表現の用法が少なくて結構認知負荷が軽い方法で代替え案を教えて頂いて助かりました。 repel it を用いた再現性や汎用性の確保、凡例の提示も助かりました。 今回は本当にありがとうございました。
guest

0

line.py

python3

1import re 2 3def convert(line): 4 m = re.search(r"^(.*.jpeg_)(\d+)(.*)$", line) 5 if m: 6 return "{}{}{}".format(m.group(0), m.group(0), m.group(2)) 7 else: 8 return line 9 10 11TEST = [ 12 "Re_a_img063c.jpg_1.csv", 13 "Re_a_img063c.jpg_21.csv", 14 "Re_a_img063c.jpg_100.csv", 15 "Re_b_img065c.jpg_3.csv", 16 17 "Re_b_img065c.jpg_A.csv", 18 19 "Re_c_img065c.jpg_1234567890134567890.csv", 20 "Re_d_img065c.jpg_0.csv" 21 "Re_e_img065c.jpg_0_1.csv" 22] 23 24result = [convert(line) for line in TEST] 25print("\n".join(result)) 26

実行例
イメージ説明

投稿2020/03/02 13:48

katoy

総合スコア22324

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問