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

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

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

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

Python

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

Q&A

解決済

1回答

2548閲覧

文字列から正規表現を使って英単語のみを抽出する

ETOLEA

総合スコア15

正規表現

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

Python

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

0グッド

0クリップ

投稿2021/10/20 09:35

編集2021/10/20 09:43

#やりたいこと

  • Python 3.9.5

ここにひとつの文字列があります

python

1'{q:2,num:20,title:"バラバラフィスティバル!",width:596,height:686,xalign:10,yalign:10,stage:[[2,1,2,7],[3,2,1,3,2],[6,3,3,3,1],[4,1,1,2,5],[1,2,1,3,2,5],[2,1,1,2,3,3,1],[2,2,1,1,2,1],[1,3,1,1,1],[2,1,4,1,1],[2,1,4,1,1],[1,2,4,1,1],[4,1,1,1],[2,2,1,1,2,1],[1,1,2,2,3,3,1],[3,1,3,2,5],[5,1,1,2,5],[6,3,2,5],[6,2,4,3,1],[3,1,1,4,2],[2,2,8],[1,2,4,2,3],[2,2,2,2,4],[3,2,2,5],[5,5,5],[4,2,3,5],[3,3,3,3,4],[3],[7,3,7],[2,2,5,2,2],[3,1,1,3,2],[2,1,1,1,1],[1,4,6],[5,7],[3,3],[2,3,4,2],[1,5,6,1],[1,16,1],[1,3,4,1],[2,14,2],[3,3]],chk:0}'

「:」を対にして辞書のような形式に見えますが、Pythonで辞書として扱うにはkeyの部分を
ダブルクォーテーションで囲ってあげる必要があります。

ライブラリreのfindallと正規表現を使って、「,」と「:」の間にある何文字かをリストとして
取り出してあげて、ダブルクォーテーションを付けた後にまた元に戻してあげられないかを考えています。

つまりはこういうことですね

Python

1import re 2 3text = "辞書っぽいひとつの文字列" 4 5key_list = re.findall(r",(.*?):", text)

r",(.*?):" について簡単に説明すると
「,」と「:」の間にある何文字かを指定しています。
一番最初の「,」から一番最後の「:」まで全部含まれてしまわないよう「?」つき

さて、このkey_listを主力してみましょう。

Python

1# 見やすいようにfor文 2for key in key_list: 3 print(key)

result

1num 2title 3width 4height 5xalign 6yalign 7stage 81,2,7],[3,2,1,3,2],[6,3,3,3,1],[4,1,1,2,5],[1,2,1,3,2,5],[2,1,1,2,3,3,1],[2,2,1,1,2,1],[1,3,1,1,1],[2,1,4,1,1],[2,1,4,1,1],[1,2,4,1,1],[4,1,1,1],[2,2,1,1,2,1],[1,1,2,2,3,3,1],[3,1,3,2,5],[5,1,1,2,5],[6,3,2,5],[6,2,4,3,1],[3,1,1,4,2],[2,2,8],[1,2,4,2,3],[2,2,2,2,4],[3,2,2,5],[5,5,5],[4,2,3,5],[3,3,3,3,4],[3],[7,3,7],[2,2,5,2,2],[3,1,1,3,2],[2,1,1,1,1],[1,4,6],[5,7],[3,3],[2,3,4,2],[1,5,6,1],[1,16,1],[1,3,4,1],[2,14,2],[3,3]],chk

最後が惜しいです。数字のリストの中にも「,」が使われているのでそちらを先に拾ってしまいました。
また、一つ目のkey「q」の前には「,」がないので取りこぼしてしまいました。

##その他に試したこと
そのほかにもこのような正規表現も試しました。

Python

1import re 2 3text = "辞書っぽいひとつの文字列" 4 5# 取りこぼし回避に意図的に","を先頭に付与して上書き、あとでまた消す? 6text = text.replace("{", "{,") 7 8key_list = re.findall(r",(\D+):", text)

今度は「,」と「:」の間にある数字以外の文字列(\D+)を指定してみました。
結果は

result

1q 2num 3title:"バラバラフィスティバル!",width 4height 5xalign 6yalign 7stage 8chk

少し希望の出力に近づきましたが、今度はtitle直後の「:」が認識されず
クオーテーションなどをエスケープしましたが変化なしでした。

##教えてほしいこと
未熟な私の考えつく限りは尽くしました。
ここで希望する出力さえ出せればあとは冒頭の説明通りクオーテーションを付けて
元に戻し、evalを使用して実際に辞書として使っていきたいと思います。

質問内容としては、「うまく取り出す方法や改善点をご教示ください」です。
その他、根本的な着眼点のミスや解決方法もお受付しております。

拙い説明ですが、どうぞよろしくお願いします。

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

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

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

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

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

lehshell

2021/10/20 10:11

すでに辞書化の回答が出ているので、正規表現について key にしたい部分はアルファベットで始まっていますから key_list = re.findall(r"[,{]([a-zA-Z].*?):", text) で抽出できるでしょう。
otn

2021/10/20 11:57

(\D+)でなく(\D+?)にしていれば、このデータについてはうまくいくでしょう。 最初は ? を付けてたのに何故忘れちゃったんでしょう?
guest

回答1

0

ベストアンサー

stackoverflowに同じようなこと質問してる人がいて、それのBAになってるこれ

https://stackoverflow.com/a/50947875

を使ったら一応できるっぽい。
どうするかというと、その長い文字列

python

1text = '{q:2,num:20,title:"バラバラフィスティバル!",width:596,height:686,xalign:10,yalign:10,stage:[[2,1,2,7],[3,2,1,3,2],[6,3,3,3,1],[4,1,1,2,5],[1,2,1,3,2,5],[2,1,1,2,3,3,1],[2,2,1,1,2,1],[1,3,1,1,1],[2,1,4,1,1],[2,1,4,1,1],[1,2,4,1,1],[4,1,1,1],[2,2,1,1,2,1],[1,1,2,2,3,3,1],[3,1,3,2,5],[5,1,1,2,5],[6,3,2,5],[6,2,4,3,1],[3,1,1,4,2],[2,2,8],[1,2,4,2,3],[2,2,2,2,4],[3,2,2,5],[5,5,5],[4,2,3,5],[3,3,3,3,4],[3],[7,3,7],[2,2,5,2,2],[3,1,1,3,2],[2,1,1,1,1],[1,4,6],[5,7],[3,3],[2,3,4,2],[1,5,6,1],[1,16,1],[1,3,4,1],[2,14,2],[3,3]],chk:0}'

に対して、

python

1import re 2import json 3 4json_text = re.sub("(\w+):", r'"\1":', text) 5dic = json.loads(json_text)

とすると、dicに辞書が入ってくると思われます。


補足:

上記の回答についているコメントの

This regex approach is very unsafe. It will alter values that happen to contain colons. See my answer for a safe solution.

Inigo May 4 '20 at 19:49

は気になる指摘なので、ETOLEAさんご自身の問題解決において、そのまま使って問題ないかを点検する必要はありそうです。

投稿2021/10/20 09:53

編集2021/10/20 10:07
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ETOLEA

2021/10/20 10:17

頂いたソリューションでばっちりでした! 早期ご解答まことに感謝です!
退会済みユーザー

退会済みユーザー

2021/10/20 10:20

それはよかったですう〜????
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問