【问题标题】:How to translate ruby regex to javascript? - (?i-mx:..) and Rails 3.0.3如何将 ruby​​ 正则表达式翻译成 javascript? - (?i-mx:..) 和 Rails 3.0.3
【发布时间】:2011-01-31 18:44:27
【问题描述】:

我正在使用 validates_format_of 方法检查电子邮件格式:

validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i

我也使用 livevalidation 插件来验证表单,所以在我的代码中我得到:

(?i-mx:^([^@\\s]+)@((?:[-a-z0-9]+\\.)+[a-z]{2,})$)

Javascript 无法读取此正则表达式。我如何或在哪里可以将此正则表达式更改为原始表达式:

/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i

?

【问题讨论】:

标签: javascript ruby-on-rails regex


【解决方案1】:

Ruby 和 JavaScript 正则表达式由具有不同功能的不同引擎解析和执行。正因为如此,Ruby 和 JavaScript 正则表达式有细微的差别,有些不兼容。如果您注意它们不直接翻译,您仍然可以在 JavaScript 中表示简单的 Ruby 正则表达式。

这里是what client side validations does

class Regexp
  def to_javascript
    Regexp.new(inspect.sub('\\A','^').sub('\\Z','$').sub('\\z','$').sub(/^\//,'').sub(/\/[a-z]*$/,'').gsub(/\(\?#.+\)/, '').gsub(/\(\?-\w+:/,'('), self.options).inspect
  end
end

最近的addition of the routes inspector to rails 采用a similar approach,也许更好,因为它避免了猴子补丁:

def json_regexp(regexp)
  str = regexp.inspect.
        sub('\\A' , '^').
        sub('\\Z' , '$').
        sub('\\z' , '$').
        sub(/^\// , '').
        sub(/\/[a-z]*$/ , '').
        gsub(/\(\?#.+\)/ , '').
        gsub(/\(\?-\w+:/ , '(').
        gsub(/\s/ , '')
  Regexp.new(str).source
end

然后要将这些插入到您的 javascript 代码中,请使用以下内容:

var regexp = #{/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i.to_javascript};

【讨论】:

  • 转换 /.+@.+\..+/i 会导致句号双重转义,即它不起作用。
  • 对我来说似乎工作正常:puts /.+@.+\..+/i.to_javascript 给了/.+@.+\..+/i
  • 也就是说,现代 ruby​​ 正则表达式引擎似乎使正则表达式处于相当兼容的状态,因此对于许多正则表达式,您可能不需要翻译。例如,在 Ruby 2.4.1 上:puts /.+@.+\..+/i.inspect 也输出 /.+@.+\..+/i
  • gsub 方法可以有一定的效果,但这些解决方案的几乎每一行都是不正确的。顶部示例将包含不兼容的标志,底部示例将删除所有标志。 “\Z”不等同于“$”。 "(\?#.+)" 将杀死所有后续组。选项组可以不带“-”或“:”出现。除了“x”模式之外,空格有意义的。
  • 非常感谢to_javascript是一种神奇的方法,对我来说很顺利
【解决方案2】:

原因是您正在使用 .to_s 而不是 .inspect 转换正则表达式。您需要在视图中做的是使用 .inspect 来获得正确的格式。这是一些应该解释问题的示例代码:

email = /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
email.to_s #"(?i-mx:^([^@\\s]+)@((?:[-a-z0-9]+\\.)+[a-z]{2,})$)"
email.inspect #"/^([^@\\s]+)@((?:[-a-z0-9]+\\.)+[a-z]{2,})$/i"

所以,在你的 javascript 视图中做这样的事情来获得你想要的实际字符串表示:

<%= email.inspect %>

【讨论】:

    【解决方案3】:

    我编写了一个小 gem,可以将 Ruby 正则表达式转换为 JavaScript:

    https://github.com/janosch-x/js_regex

    它可以处理比 gsub 方法更多的情况,并且如果仍然存在任何不兼容性,它会包含警告。

    请注意,无论您做什么,并非所有 Ruby 正则表达式都可以完全转换为 JS,因为 Ruby 的正则表达式引擎 has a lot of features that JavaScript's doesn't have

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      相关资源
      最近更新 更多