为什么分裂(”)试图(太)聪明?

我刚刚发现了String#split的以下奇怪行为:

 "a\tb c\nd".split => ["a", "b", "c", "d"] "a\tb c\nd".split(' ') => ["a", "b", "c", "d"] "a\tb c\nd".split(/ /) => ["a\tb", "c\nd"] 

源 (string.c from 2.0.0)超过200行,包含如下所示的段落:

 /* L 5909 */ else if (rb_enc_asciicompat(enc2) == 1) { if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' '){ split_type = awk; } } 

之后,在awk split类型的代码中,实际参数甚至不再使用,并且与普通split相同。

  • 有没有人觉得这有点被打破了?
  • 这有充分的理由吗?
  • 这样的“魔术”是否比大多数人在Ruby中想象的更频繁?

它与Perl的split()行为一致。 而这又基于Gnu awksplit() 。 所以这是源于Unix的悠久传统。

split的perldoc :

作为另一种特殊情况,当省略PATTERN或由单个空格字符组成的文字字符串(例如”或“\ x20”,但不是eg / /)时,split会模拟命令行工具awk的默认行为。 在这种情况下,EXPR中的任何前导空格都会在拆分发生之前被删除,而PATTERN则被视为/ \ s + /; 特别是,这意味着任何连续的空格(而不仅仅是单个空格字符)都用作分隔符。 但是,通过指定模式/ /而不是字符串“”可以避免这种特殊处理,从而只允许单个空格字符作为分隔符。

查看文档 ,特别是以下部分:

如果pattern是String,则在拆分str时将其内容用作分隔符。 如果pattern是单个空格,则str在空白上拆分,前导空格和连续空格字符的运行被忽略。

如果省略pattern,则值为$; 用来。 如果$; 是nil(这是默认值),str在空格上分割,就像指定了`’一样。

您可以使用正则表达式来拆分字符串。