倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

Java と XML と空白と (3) : String#trim() メソッド

前回Java での「whitespace」のややこしい扱いを見ましたが、哀しいかな、他にも「whitespace」のややこしい扱いがあります。 それは String#trim() です。

String#trim() の JavaDoc をみると、

Returns a copy of the string, with leading and trailing whitespace omitted.

と書かれていて、先頭と後尾の「whitespace」を取り除くと書いてあります。

ただし、これ以降を読むと、「whitespace」とは「文字コードが \u0020 以下の文字」つまり、文字コードが \u0000 〜 \u0020 の33文字*1と定義されています。 これは前回みた Java での「whitespace」の定義と異なっています。

\u0001 〜 \u0020 までの文字は以下のようになっています(\u0000 は省略):

Unicode 文字 Unicode 文字 Unicode 文字 Unicode 文字
\u0001 \u0009 "\t" \u0011 \u0019
\u0002 \u000a "\n" \u0012 \u001a
\u0003 \u000b \u0013 \u001b
\u0004 \u000c "\f" \u0014 \u001c
\u0005 \u000d "\r" \u0015 \u001d
\u0006 \u000e \u0016 \u001e
\u0007 \u000f \u0017 \u001f
\u0008 "\b" \u0010 \u0018 \u0020 " "


文字コードの名前は以下の通り(Unicode 5.1 を参考にしたので、Java での名前は少し違うかも):

Unicode 名前 Unicode 名前 Unicode 名前
\u0000 NULL \u000b LINE TABULATION
(VT)
\u0016 SYNCHRONOUS IDLE
\u0001 START OF HEADING \u000c FORM FEED
(FF "\f")
\u0017 END OF TRANSMISSION BLOCK
\u0002 START OF TEXT \u000d CARRIAGE RETURN
(CR "\r")
\u0018 CANCEL
\u0003 END OF TEXT \u000e SHIFT OUT \u0019 END OF MEDIUM
\u0004 END OF TRANSMISSION \u000f SHIFT IN \u001a SUBSTITUTE
\u0005 ENQUIRY \u0010 DATA LINK ESCAPE \u001b ESCAPE
\u0006 ACKNOWLEDGE \u0011 DEVICE CONTROL ONE \u001c INFORMATION SEPARATOR FOUR
\u0007 BELL \u0012 DEVICE CONTROL TWO \u001d INFORMATION SEPARATOR THREE
\u0008 BACKSPACE
("\b")
\u0013 DEVICE CONTROL THREE \u001e INFORMATION SEPARATOR TWO
\u0009 CHARACTER TABULATION
(HT "\t")
\u0014 DEVICE CONTROL FOUR \u001f INFORMATION SEPARATOR ONE
\u000a LINE FEED
(LF "\n")
\u0015 NEGATIVE ACKNOWLEDGE \u0020 SPACE
(" ")

String#trim() で「whitespace」とみなされる文字はの集合は、XMLJava正規表現で「whitespace」とみなされる文字を全て含んでいます。 一方、Character#isWhitespace() で定義される「whitespace」の文字集合との間に包含関係はありません。

{XML の空白} ⊂ {Java 正規表現の空白} ⊂ {Java String#trim() の空白}

この「whitespace」の定義の違いが、どの程度影響があるのかよく分かりませんが(あまりないのかも知れません*2)、JavaDoc を一見してそれが分からないこと自体が問題かと。

*1:16進数であることに注意

*2:全角スペース (\u3000) は Character#isWhitespace() では「whitespace」とみなされますが、String#trim() では「whitespace」とみなされない、というのが日本語にとって注意が必要なところでしょうか? あまり困ったことはありませんけど(笑)