正規表現の\dが全角数字にマッチするプログラミング言語
このページは、正規表現の \d
が全角数字にマッチするプログラミング言語について調査した結果をまとめる予定のページです。
目次
注意
- 記載しているのは現状一部のプログラミング言語のみです。(今後増えるかもしれません)
- ここでいう「半角数字」は U+0030 DIGIT ZERO (0)~U+0039 DIGIT NINE (9)、「全角数字」はU+FF10 FULLWIDTH DIGIT ZERO (0)~U+FF19 FULLWIDTH DIGIT NINE (9) のことです。
まとめ
言語 | デフォルトで\dが全角数字にマッチするか | オプションなどの影響で\dの挙動が変わるか |
---|---|---|
C# (.NET) | ○ | ○ (RegexOptions.ECMAScript で半角数字のみにマッチ) |
Java | - | ○ ((?U) で全角数字にもマッチ) |
JavaScript | - | - |
Perl | - | ○ (utf8フラグ付き文字列の場合全角数字にもマッチ) |
PHP | - | ○ (u 修飾子で全角数字にもマッチ) |
Python | ○ | ○ ((?a) , re.ASCII で半角数字のみにマッチ) |
Ruby | - | ○ ((?u) で全角数字にもマッチ) |
- 明確に半角数字の0~9にのみマッチさせたい場合は、
\d
ではなく[0-9]
と書いたほうが問題が発生する可能性が低くなります。
各言語のサンプルコード
C#
using System.Text.RegularExpressions;
public class Test {
public static void Main(){
// System.Console.WriteLine(System.Environment.Version); // 4.0.30319.42000 (CLR)
var s = "1"; // 全角数字
var r1 = Regex.IsMatch(s, @"\d"); // true
var r2 = Regex.IsMatch(s, @"\d", RegexOptions.ECMAScript); // false (ECMAScript準拠)
}
}
Java
import java.util.regex.*;
public class Main {
public static void main(String[] args) throws Exception {
// System.out.println(System.getProperty("java.version")); // 17
String s = "1"; // 全角数字
boolean r1 = s.matches("\\d"); // false
boolean r2 = s.matches("(?U)\\d"); // true (埋め込みフラグの「(?U)」でUnicodeフラグを指定)
System.out.println(r2);
Pattern p = Pattern.compile("\\d", Pattern.UNICODE_CHARACTER_CLASS);
boolean r3 = p.matcher(s).matches(); // true (正規表現のコンパイル時にUnicodeフラグを指定)
}
}
JavaScript
// console.log(process.version); // v16.14.0 (node.js)
const s = '1';
const r1 = /\d/.test(s); // false
const r2 = /\d/u.test(s); // false (u修飾子を指定しても変化しない)
- 参考
- 補足
- 古いFirefoxでは
\d
が全角数字にマッチしていました。(JavaScriptの正規表現で、メタ文字の"\s","\d"はクロスブラウザでの互換性が無い。(追記@2007/11/29) - Enjoy*Study)
- 古いFirefoxでは
Perl
use Encode;
# print($[); # 5.034000
my $s = '1';
my $r1 = $s =~ /\d/; # 0
my $r2 = Encode::decode_utf8($s) =~ /\d/; # 1 (utf8フラグ付き文字列。use utf8している場合でも同じ)
PHP
// echo PHP_VERSION; // 8.1.7
$s = '1';
$r1 = preg_match('/\d/', $s) === 1; // false
$r2 = preg_match('/\d/u', $s) === 1; // true (u修飾子指定)
Python
import re
# import sys
# print(sys.version) # 3.8.10 (default, Nov 26 2021, 20:14:08)
s = "1"; # 全角数字
r1 = re.search(r'\d', s) is not None # True (PythonのデフォルトがUnicodeフラグONのためマッチする)
r2 = re.search(r'(?a)\d', s) is not None # False (埋め込みフラグの「(?a)」でASCIIフラグを指定)
p = re.compile(r'\d', re.ASCII)
r3 = p.search(s) is not None # False (正規表現のコンパイル時にASCIIフラグを指定)
Ruby
# puts RUBY_VERSION # 3.1.0
s = '1'
r1 = s.match(/\d/) != nil # false
r2 = s.match(/(?u)\d/) != nil # true (Unicodeオプション指定)