如何在Ruby Regex中转义两个正斜杠

时间:2014-06-03 17:57:28

标签: ruby regex

我正在尝试制作一个使用Ruby查找域名的正则表达式,所以我尝试了这个:

(?<=.*/).(?=.*/)

在Rubular上我总是看到此错误消息:Forward slashes must be escaped.

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:5)

当您使用//正则表达式文字时,您需要使用反斜杠/来转义\/。如果您希望在正则表达式中使用文字/,则通常更容易避免使用//字面值。例如,将%r字面值与任何不会导致冲突的分隔符一起使用。

%r{/}

顺便说一句,Ruby onigmo正则表达式引擎不允许使用可变长度查看后面,所以你的正则表达式无论如何都会返回错误。

答案 1 :(得分:2)

不要重新发明轮子,特别是那些有效的轮子:

require 'uri'

URI.split('http://user:passwd@www.example.com:81/path/to/index.html?foo=bar#baz')
# => ["http",
#     "user:passwd",
#     "www.example.com",
#     "81",
#     nil,
#     "/path/to/index.html",
#     nil,
#     "foo=bar",
#     "baz"]

或者:

require 'addressable/uri'

uri = Addressable::URI.parse('http://user:passwd@www.example.com:81/path/to/index.html?foo=bar#baz')
uri.authority # => "user:passwd@www.example.com:81"
uri.fragment # => "baz"
uri.host # => "www.example.com"
uri.password # => "passwd"
uri.path # => "/path/to/index.html"
uri.port # => 81
uri.query # => "foo=bar"
uri.query_values # => {"foo"=>"bar"}
uri.scheme # => "http"
uri.to_hash # => {:scheme=>"http", :user=>"user", :password=>"passwd", :host=>"www.example.com", :port=>81, :path=>"/path/to/index.html", :query=>"foo=bar", :fragment=>"baz"}
uri.user # => "user"

在两者之间,Addressable::URI功能更全面,并且非常密切地遵循规范。 Ruby的内置URI适合轻量级提升。

在他们的代码中扎根,你会发现用于撕开URL的正则表达式;你也会发现它们并不是微不足道的,因为网址可能非常“有趣”,“有趣”意味着你会尖叫并拔出你的头发。有关详细信息,请参阅URI RFC。有关建议的模式,请参阅该文档中的“使用正则表达式解析URI引用”。


  

...我在代码大战中进行练习,不允许使用require

首先,如果是这样,你为什么要求如何写这个?你应该自己解决这些问题。

那说,试试已经创造的东西。这使用RFC中的模式:

URI_REGEX = %r!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?!
uri_captures = 'http://user:passwd@www.example.com:81/path/to/index.html?foo=bar#baz'.match(URI_REGEX).captures # !> assigned but unused variable - port
# => ["http:",
#     "http",
#     "//user:passwd@www.example.com:81",
#     "user:passwd@www.example.com:81",
#     "/path/to/index.html",
#     "?foo=bar",
#     "foo=bar",
#     "#baz",
#     "baz"]
user, passwd, host, port = uri_captures[3].split(/[:@]/)
host # => "www.example.com"

为了进一步方便,这里提供了一个提供命名捕获的简单模式:

URI_REGEX = %r!^((?<scheme>[^:/?#]+):)?(//(?<authority>[^/?#]*))?(?<path>[^?#]*)(\?(?<query>[^#]*))?(?<fragment>#(.*))?!
uri_captures = 'http://user:passwd@www.example.com:81/path/to/index.html?foo=bar#baz'.match(URI_REGEX)
authority_captures = uri_captures['authority'].match(/(?<user>[^:]+)?:?(?<passwd>[^@]+)?@?(?<host>.+)(:(?<port>\d+)?)/)
authority_captures['host']
# => "www.example.com"