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

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

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

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

正規表現

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

Q&A

解決済

1回答

833閲覧

正規表現、re.VERBOSEと全角空白?

N-B-I

総合スコア12

Python 3.x

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

正規表現

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

0グッド

0クリップ

投稿2020/03/07 09:27

編集2020/03/07 14:30

経緯

参考書籍を丸写ししたはずなのにマッチせずmo == Noneになります。
ガチャガチャしてるうちに何故か期待する動作をしたので新旧を比較したのですが…
以下のコード2例は一見同一のコードですが結果が違います。
↓新コード
新コード
↓旧コード
旧コード
(わかりやすくするためにペイントで緑線を引いています)
よく見るとなんかズレてる…
旧コードの#3桁の番号の左に挟まっているスペースを全て打ち直したところ新コードと同じ結果に。
これで病巣はわかりましたが…

質問群

質問1
旧コードには全角の空白文字が挟まっているはずです。
ドキュメントre.VERBOSEによれば、

パターン中の空白は、文字クラス中にあるときと、エスケープされていないバックスラッシュの後にあるときと、 *? 、 (?: や (?P<...> のようなトークン中を除いて無視されます。

とあるのでデバッグ中そもそも空白文字が病巣の可能性を排除していた節があるのですけど、
「パターン中の空白」とは全角空白は対象外なのでしょうか?
プログラミングに関するドキュメントで文字種が言及される際、
原則半角に限定してのものと思っておいていいんでしょうか?

質問2
また今回、全角空白が不運にも文字列内にあったばっかりに
SyntaxError: invalid character in identifier
にも引っかからず、原因がそれとわかるまでかなりの労力を食ってしまったのですが、
実際問題皆さんはどう対策されていますか?

投稿前に自己解決しました
zenkaku

実際のコード(内容は無関係なので読まなくて構いません)

新コード

python3

1#! python3 2# 事前に'777-777-7777'をコピー 3 4import pyperclip 5import re 6 7phone_regex = re.compile(r'''( 8 (\d{3}|(\d{3}))? #市外局番 9 (\s|-|.)? #区切り 10 (\d{3}) #3桁の番号 11 (\s|-|.) #区切り 12 (\d{4}) #4桁の番号 13 (\s*(ext|x|ext.)\s*(\d{2,5}))? #内線番号 14 )''', re.VERBOSE) 15 16print(pyperclip.paste()) # 777-777-7777 17ttext = str(pyperclip.paste()) 18print(ttext) # 777-777-7777 19mo = phone_regex.search(ttext) 20print('mo:' + str(mo)) # mo:<re.Match object; span=(0, 12), match='777-777-7777'> 21mo = phone_regex.search('777-777-7777') 22print('mo:' + str(mo)) # mo:<re.Match object; span=(0, 12), match='777-777-7777'> 23```--- 24**旧コード** 25```python3 26#! python3 27# 事前に'777-777-7777'をコピー 28 29import pyperclip 30import re 31 32phone_regex = re.compile(r'''( 33 (\d{3}|(\d{3}))? #市外局番 34 (\s|-|.)?      #区切り 35 (\d{3}) #3桁の番号 36 (\s|-|.) #区切り 37 (\d{4}) #4桁の番号 38 (\s*(ext|x|ext.)\s*(\d{2,5}))? #内線番号 39 )''', re.VERBOSE) 40 41print(pyperclip.paste()) # 777-777-7777 42ttext = str(pyperclip.paste()) 43print(ttext) # 777-777-7777 44mo = phone_regex.search(ttext) 45print('mo:' + str(mo)) # mo:None 46mo = phone_regex.search('777-777-7777') 47print('mo:' + str(mo)) # mo:None

解決後記

otnさん御回答ありがとうございます。
2度と全角空白には負けません。>IMEの設定を変更 も併せて厳重に再発予防します…

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

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

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

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

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

guest

回答1

0

ベストアンサー

質問1
その通りです。

質問2
お書きのような、エディターで全角空白を可視化するのも必要ですが、
そもそも、IMEの設定を変更して、全角空白を意図せずに入力してしまうことが無いようにします。

投稿2020/03/07 09:59

otn

総合スコア85901

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問