【问题标题】:Different and same Regex in Ruby and JS on the same inputRuby和JS中相同输入的不同和相同的正则表达式
【发布时间】:2019-09-27 02:33:23
【问题描述】:

这是输入行"!!!??"

FIRST 正则表达式在 Ruby 和 JS 中的工作方式类似,并执行所需的操作将输入拆分为包含“!”的两行和 ”?”分别:

示例#1 ruby​​ like js /!+|\?+/g

RUBY s.scan(/!+|\?+/).inspect 像 JS s.match(/!+|\?+/g) 一样工作。 输出为:RUBY [ '!!!', '??' ], JS [\"!!!\", \"??\"]

示例#2 ruby​​ 不是 js /([?!])\1*/

这里 ruby​​ 和 js 有不同的行为 RUBY s.scan(/([?!])\1*/) 不等于 JS s.match(/([?!])\1*/g)。 RUBY 返回两个数组[[\"!\"], [\"?\"]]。 JS 返回两个字符串,就像示例 #1 [ '!!!', '??' ] 中一样。

为什么/([?!])\1*/ 在 Ruby 和 JS 中的行为不同?

代码https://goo.gl/

【问题讨论】:

  • @musefan match 只返回一个匹配项。
  • @WiktorStribiżew:我不知道 ruby​​,我只是 seen this 并认为它看起来是正确的,但第二次看起来你是正确的

标签: javascript ruby regex


【解决方案1】:

由于scan 仅在模式中定义捕获组时返回捕获的子字符串,因此您应该修改模式以捕获整个匹配并添加更多 Ruby 代码(编辑 as per this comment):

s="!!!??"
matches = s.scan(/(([?!])\2*)/).inject([]) { |acc, (m, _)| acc << m }
puts matches
# = ['!!!', '??']

请参阅online Ruby demo

根据@mudasobwa's comment,您甚至可以将其承包给

"!!!??".scan(/(([?!])\2*)/).map(&:first)

这里,(([?!])\2*) 匹配与 /([?!])\1*/ 相同的文本,但由于整个模式都用捕获括号包裹,所以对 ?! 的反向引用现在 ID=2,因此 \1 转进入\2。在块内,可以通过m(整个匹配)和n?!)访问捕获的值。我们只收集整场比赛,因此每场比赛都会将m 添加到matches

【讨论】:

  • @mudasobwa 是的,这个速记会让它更短。以防万一有人想对第二个捕获组进行一些“技术”访问,扩展版本可能仍然有价值。
  • 扩展后的版本应该是"!!!??".scan(/(([?!])\2*)/).inject({}) { |acc, (m, _)| acc &lt;&lt; m },不会用局部变量将累加器泄漏到全局空间:)
  • @mudasobwa 这很有趣。我在发帖时关注了this answer,我敢打赌你也可以这么说,对吧?
  • 是的。我们可以召唤@Stefan 确认:)
猜你喜欢
  • 1970-01-01
  • 2015-07-14
  • 2017-11-08
  • 2011-09-17
  • 1970-01-01
  • 2022-06-10
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多