【问题标题】:What is the precise definition of Javascript's string.split?Javascript 的 string.split 的准确定义是什么?
【发布时间】:2019-05-22 18:50:03
【问题描述】:

今天有些东西对我有用,但我不确定我是否理解它足以确定它会在随机的未来 Javascript 版本中工作。

我想在空格上使用类似 string.split() 的东西,但这也会返回分隔符字符串。换句话说:

f("abc   def ghi")
 => ["abc", "   ", "def", " ", "ghi"] 

我的第一次尝试是十几行丑陋的正则表达式搜索和循环。

然后我有一个疯狂的想法,我认为我认为工作的可能性很小,但值得快速测试:做一个.split,它可以匹配分隔符和非分隔符范围。令我高兴和惊讶的是,这基本上奏效了:

"abc   def ghi".split(/([^\s]+|[\s]+)/)
  => ["", "abc", "", "   ", "", "def", "", " ", "", "ghi", ""]

再做一点小调整,我就得到了我需要的东西:

"abc   def ghi".split(/([^\s]+|[\s]+)/).filter(s=>s.length)
 => ["abc", "   ", "def", " ", "ghi"]

当然,问题在于我可以想象 Javascript 实现在这个有点病态的正则表达式上会有不同的行为。

我可以依赖这种行为始终有效吗?为什么?规范记录在哪里?

对于“额外的功劳”,您能否给出一个直观的论据,为什么这种行为是最合理的?

【问题讨论】:

  • 这种行为似乎是合理的——我不会称这个正则表达式或split 的行为是病态的,但我也无法解释为什么它比任何其他 JS 都“最合理”特征。如果您不关心空字符串,可以使用"abc def ghi".match(/\s+|\S+/g)。虽然这似乎过于宽泛,但我认为这种欺骗并不准确,因为 OP 意识到 JS 引擎存在并且它们会随着时间而变化。
  • 简单地按字边界分割:str.split(/\b/).
  • 我不明白副本和这个问题之间的关系是什么。我确定有一个副本,但不是被选中的。
  • 是的。这就是为什么(\s+)。 + 将匹配多个空格。 () 包装器将确保在输出中也添加分隔符。
  • 一个更好的、定义明确的方法可以得到你想要的结果(不需要过滤结果)是:string.match(/([^\s]+|[\s]+)/g)

标签: javascript string


【解决方案1】:

如果split 的参数是带有捕获组的正则表达式,则匹配的组将作为返回数组中的单个项目返回。此外,如果正则表达式包含多个捕获组,它们都将作为单独的元素包含在返回数组中。

let input = 'a 8_b 0_c';
console.log(input.split(/ \d_/));
console.log(input.split(/ (\d)_/)); // includes numbers
console.log(input.split(/( )(\d)_/)); // includes spaces and numbers
console.log(input.split(/( )(\d)(_)/)); // includes spaces, numbers, and underscores

因此,对于您的用例,您可以将解决方案简化为

let x = "abc   def ghi".split(/(\s+)/);
console.log(x);

MDN reference

如果separator是包含捕获括号的正则表达式,则每次匹配separator时,捕获括号的结果(包括任何未定义的结果)都会拼接到输出数组中。

【讨论】:

    猜你喜欢
    • 2012-10-07
    • 2012-02-10
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    • 2014-08-04
    • 2014-07-08
    • 1970-01-01
    • 2022-01-15
    相关资源
    最近更新 更多