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

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

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

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

Q&A

解決済

1回答

1006閲覧

正規表現でraw string記法を用いたのに、エスケープシーケンスが無効化されてない

gunmed

総合スコア55

Python 3.x

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

1グッド

0クリップ

投稿2019/02/16 08:23

編集2019/02/16 08:30

###コードについて(前置き)
本題にはあまり関係ないかもですが、コードの説明をします。
d.pyのファイルには以下のように大学名・学食名・メニュー・値段がたくさん書かれているとします。もしその大学に2つ以上学食がある場合は 空白//\t のいづれか、または組み合わせで区切って表示されています。
大学名,レストラン名、メニュー名、値段円 (空白//\tで区切る) レストラン名、メニュー名、値段円**(紛らわしいのですが、大学名とレストラン名の間のみ','で区切っています。)**

具体的には以下です。
立聖大学,レストラン長閑、かれー、780円/ レストラン星、唐揚げ定食、1100円

コードの目的はメタ文字でメニュー名のすべてがひらがなで構成されたものがあるかを確かめ、あればそのメニュー名を表示させるというものです。

import re with open('10004/b.py', encoding='utf-8') as f: for row in f: columns = row.rstrip().split(',') #大学名とそれ以外を分離  shop_col = columns[1] #大学名以外のリテラルを取得 例 レストラン長閑、かれー、780円/ レストラン星、唐揚げ定食、1100円 for x in re.split('\s*[//\t]+\s*', shop_col): #レストランが2つあった場合は分離 例 レストラン長閑、かれー、780円 lis = x.split('、')[1] #メニュー名を取得 例 かれー if re.match(r'[\u3041-\u3096]+$', lis):  print(lis) #かれーはすべてひらがななので、表示

ここで、正規表現でバックスラッシュ\を使うときはエスケープシーケンスとの衝突を避けるため以下の2通りがあると学びました。
①r'\s'と文字列の前にrを置く。この場合、文字列内のエスケープシーケンスは無効になる。
②\sのようにバックスラッシュを2つ続ける。エスケープシーケンスは利用できる。

ある参考書によると、①が推奨されているらしいです。ゆえに①を使用しました。

また、上記のコードでひらがなで構成されたメニューのみを表示させるため、メタ文字で表現するため以下の方法があると学びました。
⑴[ぁ-ゖ]+$
⑵[\u3041-\u3096]+$

⑴はmacで入力方法がわからないので、⑵を使用しましした。

そして、上記のコードを作成しました。
正常に動いたのですが、一つ疑問が残りました。

###本題
[\u3041-\u3096]+$の部分ですが、\uはそもそもエスケープシーケンスで「16-bit の十六進値 xxxx を持つ文字」と公式に載っています。
リンク内容

①の方法でやっているので、r''だと文字列中のエスケープシーケンスが無効になるはずなのに、\uは正常に働いています。また、rを除いて、if re.match('[\u3041-\u3096]+$', lis): としても正常に動きました。こうなると、r''でエスケープシーケンスが無効になるというのと矛盾してしまいます。そもそも①の無効になるという定義が間違っているのかなと思い調べても、なかなかヒットしません。
どこか自分の解釈に間違えがあると思うのですが、ぜひお分かりの方、回答よろしくお願いします。

ちなみに、ひらがなのみで構成された文字列を検索するとき⑴と⑵があるとなっていたのですが、プログラマの方はどちらを使うのが普通なのかも知っていたら教えていただけるとありがたいです。たぶん、世界中の誰が見てもわかるように⑵だと思うんですけど、\uが含まれているので、扱いがめんどくさいのかなとも思っています。

mac 10.14.1
visual studio code

LouiS0616👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

文字列リテラルでのエスケープ記号と、正規表現のエスケープ記号と、それぞれ処理されます。

raw文字列リテラルで書くと、文字列リテラルのエスケープは効きませんので、\uはそのまま正規表現ライブラリに渡されます。正規表現ライブラリに於いて、\uはユニコード文字を表すエスケープシーケンス開始ですので、そのように扱われます。正規表現ライブラリにて「\sが空白文字」というのと同じレベルの話です。

投稿2019/02/16 08:35

otn

総合スコア84559

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

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

gunmed

2019/02/16 13:06

回答ありがとうございます。 なるほど、\uは正規表現ライブラリに存在して、ユニコードを表しているのですね。なかなか調べてもでてこなかったので、助かりました。 ありがとうございました。
gunmed

2019/02/18 01:45

見つかりました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問