Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(Ruby)regex可选匹配项_Ruby_Regex - Fatal编程技术网

(Ruby)regex可选匹配项

(Ruby)regex可选匹配项,ruby,regex,Ruby,Regex,我正在编写一个Rack应用程序来拆分以某些前缀结尾的主机名 例如,主机名(和端口)hello.world.lvh.me:3000需要拆分为令牌hello.world、.lvh.me和:3000。此外,前缀(hello.world)、后缀(.lvh.me)和端口(:3000)都是可选的 到目前为止,我有一个(Ruby)正则表达式,看起来像/(.*)(\.lvh\.me)(\:\d+)/ 这将成功地将主机名分解为多个组件,但当一个或多个可选组件丢失时,主机名会下降,例如hello.world:300

我正在编写一个Rack应用程序来拆分以某些前缀结尾的主机名

例如,主机名(和端口)
hello.world.lvh.me:3000
需要拆分为令牌
hello.world
.lvh.me
:3000
。此外,前缀(
hello.world
)、后缀(
.lvh.me
)和端口(
:3000
)都是可选的

到目前为止,我有一个(Ruby)正则表达式,看起来像
/(.*)(\.lvh\.me)(\:\d+)/

这将成功地将主机名分解为多个组件,但当一个或多个可选组件丢失时,主机名会下降,例如
hello.world:3000
lvh.me:3000
甚至是普通的
hello.world

我尝试向每个组添加
,使它们成为可选的(
/(.*)(\.lvh\.me)(\:(\d+)/
),但这总是以第一个组(
(.*)
)结束,捕获整个字符串并停在那里


我的直觉是,这是一个可以用lookaround解决的问题,但我承认这对我来说是一个全新的regex领域。

你可以尝试以下模式:

\A(?=[^:])(.+?)??((?:\.|\A)lvh\.me)?(:[0-9]+)?\z
前瞻
(?=[^:])
检查是否至少有一个字符不是
(换句话说,不仅仅是端口)。这意味着至少存在
hello.word
lvh.me

第一组是可选的且非贪婪的
,这意味着它仅在需要时匹配

\A
\z
是字符串开头和结尾的锚点(当
^
$
用于行时)

请注意,字符类
\d
匹配Ruby中的所有unicode数字,但在本例中,您只需要ascii数字。最好使用
[0-9]

还要注意的是,
\A(?=[^:])((?>[^l:\n.]+\Bl\l(?!vh\.me\b))*((?:\.\A)lvh\.me)(:[0-9]+)?\z
可能更有效

试试
^(.*?)(\.?lvh\.me)?(\:\d+)$

我补充说:

  • 发送到使
    *
    非贪婪的第一组
  • ^,$
    将其锚定到起点和终点
  • a
    \.
    lvh之前的
    .
    ,因为您希望匹配
    lvh.me:3000
    而不是
    。lvh.me:3000
一个标记化的答案 只是为了好玩,我决定看看是否有一种相对简单的方法可以在不使用复杂正则表达式的情况下实现您想要的功能。我唯一使用的正则表达式是用于拆分和验证的

这对我来说适用于您提供的语料库和一些变体

str    = 'hello.world.lvh.me:3000'
tokens = str.split /[.:]/
port   = tokens.last =~ /\A\d+\z/ ? ?: + tokens.pop : ''
domain = sprintf '.%s.%s', *tokens.pop(2)
prefix = tokens.join ?.

在某些情况下,您当然需要检查空字符串,但它似乎比纯正则表达式解决方案更直接和/或更灵活。无论如何,我发现它更可读。如果您确实需要一个正则表达式,我相信其他答案中的一个会帮助您解决问题。

您可以尝试拆分,而不是使用正则表达式阿奇

irb(main):012:0> "hello.world.lvh.me:3000".split(/\.(?=[^.:]+\.[^:.]+(?::\d+)?$)|:/)
=> ["hello.world", "lvh.me", "3000"]
irb(main):013:0> "hello.world:3000".split(/\.(?=[^.:]+\.[^:.]+(?::\d+)?$)|:/)
=> ["hello.world", "3000"]
irb(main):014:0> "lvh.me:3000".split(/\.(?=[^.:]+\.[^:.]+(?::\d+)?$)|:/)
=> ["lvh.me", "3000"]
irb(main):015:0> "hello.world".split(/\.(?=[^.:]+\.[^:.]+(?::\d+)?$)|:/)
=> ["hello.world"]
irb(main):016:0> "hello.world.lvh.me".split(/\.(?=[^.:]+\.[^:.]+(?::\d+)?$)|:/)
=> ["hello.world", "lvh.me"]
听着,妈妈,没有正则表达式

def split_up(str)
  str.sub(':','.:')
     .split('.')
     .each_slice(2)
     .map { |arr| arr.join('.') }
end

split_up("hello.world.lvh.me:3000") #=> ["hello.world", "lvh.me", ":3000"]
split_up("hello.world:3000")        #=> ["hello.world", ":3000"]
split_up("hello.world.lvh.me")      #=> ["hello.world", "lvh.me"]
split_up("hello.world")             #=> ["hello.world"]
split_up("")                        #=> []
步骤:

str1 = "hello.world.lvh.me:3000" #=> "hello.world.lvh.me:3000"
str2 = str1.sub(':','.:')        #=> "hello.world.lvh.me.:3000"
arr  = str2.split('.')           #=> ["hello", "world", "lvh", "me", ":3000"]
enum = arr.each_slice(2)         #=> #<Enumerator: ["hello", "world", "lvh",
                                 #     "me", ":3000"]:each_slice(2)>
enum.to_a                        #=> [["hello", "world"], ["lvh", "me"],
                                 #    [":3000"]]
enum.map { |arr| arr.join('.') } #=> ["hello.world", "lvh.me", ":3000"]
str1=“hello.world.lvh.me:3000”#=>“hello.world.lvh.me:3000”
str2=str1.sub(“:”,“.:”)#=>“hello.world.lvh.me.:3000”
arr=str2.split('.')#=>[“你好”,“世界”,“lvh”,“我”,“3000”]
enum=arr.each_切片(2)#=>#
enum.to_a#=>[“你好”,“世界”],[“lvh”,“我”],
#    [":3000"]]
enum.map{| arr | arr.join('.')}#=>[“hello.world”,“lvh.me”,“:3000”]

差不多了,但是有了
lvh.me:3000
lvh.me
被第一组而不是它自己的组捕获了。喜欢它!我今天从你的回答中学到了一些新东西。提醒一下
\A
\z
^
$
相比可能有用,这是一个非常常见的混淆点Ruby的正则表达式。尽管@casimir的答案更为可靠,但我接受了这个答案,因为它足以满足我的目的,并且是我最终使用的。基本上,我不需要正则表达式来关心是否缺少任何组,只要每个组都与它的设计相匹配,而不需要其他任何东西。你确定要
^
吗>$
而不是
\A
\z
?在这种情况下可能没有什么区别,但好习惯就是好习惯。