🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
正規表現

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

Python

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

Q&A

解決済

3回答

623閲覧

Pythonによる正規表現と文字列置換について

退会済みユーザー

退会済みユーザー

総合スコア0

正規表現

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

Python

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

0グッド

0クリップ

投稿2019/11/26 08:25

編集2019/12/04 03:22

概要

Pythonで正規表現を使った文字列置換をしたいです.

例えば以下のような文字列を

2.8.0.810? actionset/group0r actionset/group0@7053c5addbb064a28cbc26db1b5e003ebb9fa2f9e157d254bf4c792a14cb05b9 2.8.0.810"(ヨ靺?8ソ{? actionset/group1r actionset/group1@bf696e8a1579e2a8d8067bfef77a2bcffb8724020f9d6f7d9e0821a4f3bc4dbb 2.8.0.810"(ナヨ 8ノ|?

こんな風に置換したいです.

https://d2ktlshvcuasnf.cloudfront.net/Release/2.8.0.810/Android/actionset/group0 https://d2ktlshvcuasnf.cloudfront.net/Release/2.8.0.810/Android/actionset/group1

※置換対象の文字列は大量にあるのですが, これと似たような文字列が大量にあるものと考えてください.

このような文字列置換は適当なエディタを使って

置換前『^[^a-z]?(.+)\x{0012}@[0-9a-f]+\x{001A}\x{0009}([\d.]+).+$』 置換後『https://d2ktlshvcuasnf.cloudfront.net/Release/$2/Android/$1』 置換前『^(?!(https)).*$』 置換後『』 置換前『^[\r\n]』 置換後『』

このように置換をすることができますが, いちいちエディタを起動してコマンドを打つのは億劫ですよね.

実際に書いたコード.遭遇したエラー

そこで, 普段よく使う言語のPythonでこの流れを自動でできないか...と考えて, コードを書いてみました.

Python

1import os 2import re 3import codecs 4 5#文字列内に/が入る(path指定とか)場合rをつけると良い 6TXT='file' 7URL=r'https://d2ktlshvcuasnf.cloudfront.net/Release/$2/'+str(OS)+'/$1' 8f1=r'^[^a-z]?(.+)\x{0012}@[0-9a-f]+\x{001A}\x{0009}([\d.]+).+$' 9f2=r'^(?!(https)).*$' 10f3='[\n\r]' 11 12print('fileを確認します・・・') 13 14with codecs.open(TXT,"r","utf-8","ignore") as f: 15 print('正常に開くことに成功しました') 16 txt0=f.read() 17 txt1=re.sub(f1,URL,txt0) 18 txt2=re.sub(f2,"",txt1) 19 newtxt=re.sub(f3,"",txt2) 20 21with open(TXT+'.txt',"w") as f: 22 f.write(new_txt)

で,書いてみたはいいものの

re.error: incomplete escape \x at position 12

とエラーが出ます.

これは

f1=r'^[^a-z]?(.+)\x{0012}@[0-9a-f]+\x{001A}\x{0009}([\d.]+).+$'

の手前のほうの\xにエラーを吐いてるとわかるのですが,rをつけるのはエスケープを二重につけなくていいようにしているだけなはずで,いまいち何が原因でエラーを吐いているのかがわかりません.

補足

今回は表題の通り,Pythonで正規表現による文字列置換を行う方法を御教授願いたいです.

知恵を貸していただけないでしょうか.
よろしくお願いします.

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

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

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

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

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

guest

回答3

0

ベストアンサー

自己解決しました.

サクラエディタで同様に置換しようと考えたのが罠で, as fで読んだファイルに対して^で各行置換なんてできるわけがないですよね. as line で読んで適当に整理したらできました. 些細なあれでした.

エディタで置換するのとプログラム上で置換するのは全く別の話だと理解できただけでも良かったかなと思います.

※ちなみに本文では文書の都合上あまり書くことができず誤解を与えてしまって申し訳ないと思うのですが, すべての文字列にactionset/groupがつくわけではないです.

投稿2019/12/04 08:21

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

たった一回の置換で全て片付けようとするとかえってややこしいので、一行づつ処理することに。
すると、訳の分からない非英数文字へのマッチングを考えなくても良くなる。

あとは細かい文法上の問題を何箇所か修正すると、こんな感じになりました。

import os import re import codecs #文字列内に/が入る(path指定とか)場合rをつけると良い OS='Android' TXT='file' URL=r'https://d2ktlshvcuasnf.cloudfront.net/Release/$2/'+str(OS)+'/$1' #f1=r'^[^a-z]?(.+)\x12@[0-9a-f]+\x1A\x09([\d.]+).+$' #f2=r'^(?!(https)).*$' #f3='[\n\r]' f1="https://d2ktlshvcuasnf.cloudfront.net/Release/2.8.0.810/" + OS + "/" print('fileを確認します・・・') with codecs.open(TXT,"r","utf-8","ignore") as f: print('正常に開くことに成功しました') for txt0 in f: #txt1=re.sub(f1,URL,txt0) #txt2=re.sub(f2,"",txt1) #newtxt=re.sub(f3,"",txt2) #newtxt=re.sub('[\x00- ]*actionset/group(\d).* *([\d.]+)', '$1 $2', txt0) txt1=re.sub(r'.*(actionset/group[\d.]+).*', r'{}\1'.format(f1), txt0) if txt1!=txt0: print(txt1) #with open(TXT+'.txt',"w") as f: # f.write(new_txt)

投稿2019/12/04 07:41

KojiDoi

総合スコア13692

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

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

0

意図を理解しているか自信ないですが\x{HHHH}じゃなくて\xHHの形式でどうでしょうか。

適当なエディタというのが何を使ったのかわかりませんが正規表現の細かいところは言語やソフトによって違います。

投稿2019/11/26 09:01

編集2019/11/26 09:01
TaniguchiTakaki

総合スコア171

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

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

退会済みユーザー

退会済みユーザー

2019/11/27 08:38

正規表現に関する知識が浅いもので失礼いたしました. >意図を理解しているか自信ないですが\x{HHHH}じゃなくて\xHHの形式でどうでしょうか。 これは ^[^a-z]?(.+)\x{0012}@[0-9a-f]+\x{001A}\x{0009}([\d.]+).+$ ↓ ^[^a-z]?(.+)\x12@[0-9a-f]+\x1A\x09([\d.]+).+$ のように書き直すということでしょうか? ちなみに実行したエディタでは書き直した正規表現ではエラーが出ました。(too short mutibyte code string) >適当なエディタというのが何を使ったのかわかりませんが正規表現の細かいところは言語やソフトによって違います。 サクラエディタを使っています. フォーラムを調べたところ, 仰られていますように細かい表記方法が違うようですね...。
KojiDoi

2019/11/28 07:02

>ちなみに実行したエディタでは pythonで試してみないと意味ないでしょう。
退会済みユーザー

退会済みユーザー

2019/12/04 03:15

すみません, 言葉足らずでした ^[^a-z]?(.+)\x12@[0-9a-f]+\x1A\x09([\d.]+).+$ で書き直してPythonでも実行してみた所, エラーは出ていないものの上手く置換されていませんでした
KojiDoi

2019/12/04 04:41

そもそも\x12でどの文字をマッチさせたいのでしょうか。それっぽい文字が対象文字列中に見当たらないように思えるのですが。
KojiDoi

2019/12/04 06:26

↑すみません、コピペしてみたらなんとなく分かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問