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

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

ただいまの
回答率

88.63%

PYTHON 正規表現について

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 509

yuujiMotoki

score 56

pythonでの正規表現(re)で躓いています。

FLASKでローカルWEBサーバを立てて、インタネットからWEBHOOKメッセージを受けて
別のアプリにzmqでメッセージリクエストを送るコードを書いています。

WEBHOOKされるメッセージは、JSON形式で送られており、
その中に、USD/jpyといった 通貨ペアがあり、
それを正規表現で抜き出すコードを書いています。

どうやら、文字列をバイトコードで変換している旨の
警告が出ています。

    result = re.match(rb'[A-Z]{3}[\/][A-Z]{3}',res2)

TypeError: cannot use a string pattern on a bytes-like object

このコードをどう直せば、REQメッセージで送れるものでしょうか?

正規表現のライブラリ、REの使い方で躓いており、先に進めません。

すみませんが、WEB通信と、pythonについては素人なので、
そもそも書き方に自信がありません。

    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:/Users/moto/Documents/GitHub/infooff/タイトル無し0.py", line 30, in webhook
    res2 = re.match(r'[A-Z]{3}[\/][A-Z]{3}',res2)
  File "C:\Users\moto\Anaconda3\lib\re.py", line 173, in match
    return _compile(pattern, flags).match(string)
**TypeError: cannot use a string pattern on a bytes-like object**
127.0.0.1 - - [28/Aug/2019 21:18:08] "POST /?chatwork_webhook_signature=CzpZzZWtH6XWfxRAa1BW9ejjWQxh43c3qPnXM/HS3/4%3D HTTP/1.1" 500 -
#!/usr/bin/python
# -*- coding: utf-8 -*-
import json
from zmq import Context, REQ
from flask import Flask, request
import re
import pdb; 


def mains(msg):
    context = Context()
    print("Connecting to hello world server...")
    socket = context.socket(REQ)
    socket.connect("tcp://localhost:5555")
    for i in range(1):
        socket.send(msg)
        message = socket.recv()
        print("Received reply %s [ %s ]" % (i, message))

def jsonConversion(jsonStr):
    data = json.loads(jsonStr)
    return data

app = Flask(__name__)

@app.route("/", methods=['POST'])
def webhook():
    msg = request.get_data() 
    res = jsonConversion(msg)
    res2 = res['webhook_event']['body'].encode('shift-jis')
    pdb.set_trace()

    result = re.match(rb'[A-Z]{3}[\/][A-Z]{3}',res2)

    mains(result)
    return msg

if __name__ == "__main__":
    app.run()
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

提示ソースresult = re.match(rb'[A-Z]{3}[\/][A-Z]{3}',res2)
エラー内のコードres2 = re.match(r'[A-Z]{3}[\/][A-Z]{3}',res2)とが異なるのが気になりますが…

以下の方法1のようにrb'~'bytes型用の正規表現を指定、適用するか
方法2のように普通にstr型に対して正規表現を適用すればよいです。

import re

src = 'USD/JPY'

# 方法1:byte型のまま正規表現を適用する
res2 = src.encode('shift-jis')
result = re.match(rb'[A-Z]{3}[\/][A-Z]{3}',res2)
print(result) # <_sre.SRE_Match object; span=(0, 7), match=b'USD/JPY'>

# 方法2:str型に対して普通に正規表現を適用する
res2 = src
result = re.match(r'[A-Z]{3}[\/][A-Z]{3}', res2)
print(result) # <_sre.SRE_Match object; span=(0, 7), match='USD/JPY'>

追記

socket.sendにはbytes型の引数を渡さなければならず、Match objectをそのまま渡すことはできません。
以下のようにマッチした部分を取得して渡すようにしてください。

src = 'USD/JPY'

res2 = src.encode('shift-jis')
result = re.match(rb'[A-Z]{3}[\/][A-Z]{3}',res2)
print(result) # <_sre.SRE_Match object; span=(0, 7), match=b'USD/JPY'>

msg = result.group(0)
print(msg) # b'USD/JPY'

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/29 05:53 編集

    お世話になります。
    エラーコードが違っている件ですが、途中解析中のものを張り付けてしまいました。
    今回のエラーは、正規表現には問題ないことが分かりました。

    どうやら、正規表現された resultのクラスは
    FLASKの引数にできない・・・ようなエラーを吐いていました。

    つまり、class(re.Match)という型を、なんらか変換せよということなのですが
    (すこしタイトルとは、質問内容が変わってきたのですが、
    このままで、先の回答を期待できるのであれば、しばらくこのまま
    議論させて頂ければと思います)


    ‘‘‘python
    > <ipython-input-1-24aa6dcf04c0>(31)webhook()
    -> result = re.match(rb'[A-Z]{3}[\/][A-Z]{3}',res2)
    (Pdb) res2
    b'USD/JPY'
    (Pdb) n
    > <ipython-input-1-24aa6dcf04c0>(33)webhook()
    -> mains(result)
    (Pdb) result
    <re.Match object; span=(0, 7), match=b'USD/JPY'>
    (Pdb) n
    Connecting to hello world server...
    TypeError: <re.Match object; span=(0, 7), match=b'USD/JPY'> does not provide a buffer interface.
    > <ipython-input-1-24aa6dcf04c0>(33)webhook()
    -> mains(result)
    (Pdb) n
    --Return--
    > <ipython-input-1-24aa6dcf04c0>(33)webhook()->None
    -> mains(result)
    (Pdb) result
    <re.Match object; span=(0, 7), match=b'USD/JPY'>
    (Pdb) type(result)
    <class 're.Match'>
    (Pdb) n
    TypeError: <re.Match object; span=(0, 7), match=b'USD/JPY'> does not provide a buffer interface.
    > c:\users\moto\anaconda3\lib\site-packages\flask\app.py(1799)dispatch_request()
    -> return self.view_functions[rule.endpoint](**req.view_args)
    ‘‘‘

    キャンセル

  • この投稿は削除されました

  • 2019/08/29 07:05

    コメント欄ではマークダウン表記が使えないので、質問本文を編集して追記ください。

    キャンセル

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

  • ただいまの回答率 88.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る