Kotlin Regexで半角記号Punctuation Pattern

2023/07/30に公開

一般的な半角記号にマッチするRegexをシンプルに書きたかった。

Androidで使うKotlinのPatternのdocumentはこちら
https://developer.android.com/reference/kotlin/java/util/regex/Pattern

Kotlinでは \p{Punct} または \p{P} が使える
定義はこちら
https://docs.oracle.com/javase/jp/8/docs/api/java/util/regex/Pattern.html

\p{Punct} 句読文字: One of !"#$%&'()*+,-./:;<=>?@[]^_`{|}~

が、+=<>がマッチしない。

次の定義済の文字クラスとPOSIX文字クラスは、UNICODE_CHARACTER_CLASSフラグが指定されている場合、Unicode正規表現の付録C: 互換性プロパティの勧告に適合しています。

UNICODE_CHARACTER_CLASS はKotlinでサポートされてないらしい
https://youtrack.jetbrains.com/issue/KT-51858

Pattern.compile("^[0-9a-zA-Z\\p{P}]{6,40}$", UNICODE_CHARACTER_CLASS)
を定義すると @RequiresApi(Build.VERSION_CODES.N) を付与するよう警告が出るが、対応してもそもそも Pattern.compile 側が対応できていないらしくクラッシュする

Caused by: java.lang.IllegalArgumentException: Unsupported flags: 256
at java.util.regex.Pattern.<init>(Pattern.java:1394)
at java.util.regex.Pattern.compile(Pattern.java:985)

これによりKotlinの\p{Punct}には+=<>が含まれない

Unicode正規表現 = https://www.unicode.org/reports/tr18/

POSIX adds symbols. Not recommended generally, due to the confusion of having punct include non-punctuation marks.

Puctuationは句読点なのでさもありなん。
\p{S}+=<>もマッチするようになるけど、そもそもPunctuationに限った定義リストが結局見つからない上にNot recommended書かれてるのでホワイトリストで手動で書いた方が安全そう。

"^[a-zA-Z0-9!@#\$%^&*()_+={}\\[\\]:;\"'<>,.?/~`|-]+\$".toRegex()

Discussion