正規表現の\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修飾子を指定しても変化しない)

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オプション指定)