要点
- Pythonの引数なし
split()とGoのFieldsは、測った9種類の入力ですべて同じ結果だった(出典: 自社の実測・2026-10-20)。 - JavaScriptは
trim()後に空白で分割しても、空文字列では空の要素が1つ残った(出典: 自社の実測・2026-10-20)。 - Goの正規表現の
\sでは、全角スペースとノーブレークスペースを分割できなかった(出典: 自社の実測・2026-10-20)。
「空白で分ける」で何が困るのか
空白で区切った文字列から単語を取り出したいとき、区切り文字に" "を指定する方法と、引数を省略する方法は同じ結果になるとは限らない。連続した空白をひとまとまりとして扱うか、文字列の両端に空の要素を残すかで、返る内容が変わる。
Pythonの引数なしstr.split()とは、空白に従って文字列を分割し、結果から空文字列を除く処理のことだ。
この動作をJavaScriptやGoへ移す際には、「空白」という呼び方だけで処理を選べない。確認する点は、区切りとして認識する文字と、空の要素の扱いの2つだ。通常の空白で分かれることを確認しても、タブや全角スペースで分かれるとは限らない。また、連続空白で空の要素が出なくても、空文字列を渡したときまで空の要素がなくなるとは限らない。
今回の実測では、通常の空白、連続空白、両端の空白、タブ、全角スペース、ノーブレークスペース、改行、空文字列、空白だけの文字列を比較した。
公式の説明では何を区切りとして扱うのか
Pythonのstr.splitのdocstringには、引数の既定値について次の説明がある。
None (the default value) means split according to any whitespace, and discard empty strings from the result.
出典: Python 3.9.0のstr.split.__doc__(取得日 2026-10-20)
ここでは、空白に従って分割することと、空文字列を結果から除くことが明記されている。split(' ')のように区切りを指定した場合と、引数なしの場合を区別する根拠になる。
一方、JavaScriptのString.prototype.split()について、MDNは次のように説明している。
Omitting separator or passing undefined causes split() to return an array with the calling string as a single element.
出典: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split (取得日 2026-10-20)
JavaScriptでは、区切りを省略すると元の文字列を単一の要素とする配列を返す。したがって、Pythonと同じつもりで引数なしのsplit()を書くことはできない。
Goのstrings.Fieldsは、unicode.IsSpaceで定義される連続した空白の周囲で分割し、返す要素を空にしないと説明されている。先頭と末尾の連続した空白を捨てることも明記されている。対してstrings.Splitは、指定した区切りの間にある部分文字列を返す処理だ。
出典: Go 1.26.2のgo doc strings.Fields・go doc strings.Split(取得日 2026-10-20)
連続空白・両端の空白・空文字列を比べる
実測環境はmacOS 26.5.1(BuildVersion 25F80・arm64)、Python 3.9.0、Node v22.22.3、Go 1.26.2だった。同じ9個の入力を各言語に渡し、結果をJSONの形で出力した。以下は、その記録から連続空白、両端の空白、空文字列の結果を抜き出した比較表だ。
| 分割方法 | "a b" |
" a b " |
"" |
|---|---|---|---|
Python s.split() |
["a", "b"] |
["a", "b"] |
[] |
Python s.split(' ') |
["a", "", "b"] |
["", "a", "b", ""] |
[""] |
Python re.split(r'\s+', s) |
["a", "b"] |
["", "a", "b", ""] |
[""] |
Node s.split(' ') |
["a","","b"] |
["","a","b",""] |
[""] |
Node s.split(/\s+/) |
["a","b"] |
["","a","b",""] |
[""] |
Node s.trim().split(/\s+/) |
["a","b"] |
["a","b"] |
[""] |
Go strings.Split(s, " ") |
["a","","b"] |
["","a","b",""] |
[""] |
Go strings.Fields(s) |
["a","b"] |
["a","b"] |
[] |
Goの正規表現 \s+による分割 |
["a","b"] |
["","a","b",""] |
[""] |
出典: 自社の実測(2026-10-20)
連続空白の入力では、文字としての空白を指定する方法に空の要素が残った。正規表現の\s+では、その入力の途中に空の要素は残らなかったものの、両端に空白がある入力では空の要素が残った。
Nodeでtrim()を先に呼んだ場合、両端の空白がある入力はPythonの引数なしsplit()と同じ要素になった。ただし、空文字列では[""]だった。空白3つだけの入力でも[""]となり、Pythonの[]とは異なった。「両端を取り除けば同じ」と判断する前に、空の入力も比較する必要がある。
どれを使うかは空の要素と文字の範囲で決める
今回の入力に対して、空白をまとめて扱い、空の要素を残さずに分割したいなら、Pythonでは引数なしのsplit()、Goではstrings.Fieldsがその結果を返している。両者は9種類の入力すべてで同じ結果だった。
ただし、この一致をすべての文字へ広げることはできない。追加で1文字ずつ調べたU+001Cでは、Pythonのsplit()は分割したが、GoのFieldsは分割しなかった。Nodeの空白判定でも、この文字は空白として扱われなかった。
正規表現にも違いがある。全角スペースとノーブレークスペースは、PythonのreとNodeの/\s+/では分割されたが、Goの正規表現では分割されなかった。Goのregexp/syntaxに記載された文字クラスの行は次のとおりだ。
\s whitespace (== [\t\n\f\r ])
[[:space:]] whitespace (== [\t\n\v\f\r ])
出典: Go 1.26.2のgo doc regexp/syntax(取得日 2026-10-20)
この記述では、\sと[[:space:]]の範囲も異なる。垂直タブはGoの\sには当たらず、実測でも一致しなかった。同じGoで空白を扱う処理でも、Fieldsと正規表現を同じものとして選ぶことはできない。
また、Pythonの正規表現でre.ASCIIを指定した1文字ずつの判定では、全角スペースとノーブレークスペースは\sに一致しなかった。言語名に加え、使う関数や指定した設定まで比較することが必要だ。
出典: 自社の実測(2026-10-20)
自分の環境で確かめる手順
まずPythonの版と、手元のstr.splitの説明を確認する。次のコマンドは、実測記録でも説明の取得に使ったものだ。
python3 -V
python3 -I -c "print(str.split.__doc__)"
分割結果を確認するときは、通常の空白だけでなく、連続空白、両端の空白、空文字列を別々に渡す。全角スペースやノーブレークスペースを扱う入力なら、それらも分けて確かめる。比較する際は、見えている単語だけでなく、空の要素が含まれているかを見る。
ここで掲載した結果は、記載した環境での実測に限られる。Pythonの別の版で結果が変わるか、ブラウザのJavaScriptエンジンでどうなるかは確認できなかった。追加の制御文字についても、U+001C以外のU+001D〜U+001Fなどは測っていない。処理速度も測っていないため、この記事の比較から速さの優劣は判断できない。
出典: 自社の実測(2026-10-20)

コメント