我的URI字符串看起来像这样(etc
可以是任意长度):
/7/ipsum/dolor/etc
/2/not/17/ipsum/etc
这是我想要实现的目标:在正斜杠上拆分字符串,进行第二次和第三次匹配(["ipsum", "dolor"]
和["not", "17"]
),如果它不是第二个元素,则扔掉它数。所需的结果为["ipsum"]
和["not", "17"]
。
我用普通红宝石实现了这个(通过将字符串拆分成数组,然后检查所需值的值)。使用正则表达式有更好的方法吗?
答案 0 :(得分:3)
这是一个可能的实现,带有扩展的,有文档的正则表达式。
def extract_parts_from(path)
pattern = %r{
^/[^/]+ # don't capture the first element
/([^/]+) # always capture the second element
/(?:(\d+)/)? # capture the third element if it's made up of digits
}x
path.match(pattern)[1,2].compact
end
试验:
["/7/ipsum/dolor/etc", "/2/not/17/ipsum/etc"]. each do |p|
p extract_parts_from(p)
end
结果:
["ipsum"]
["not", "17"]
答案 1 :(得分:2)
此表达式将返回第二个值,如果是数字,则返回第三个值。
^/(?:[^/]*/){1}([^/]*)/(?:(\d{1,})|[^/]*)/.*?$
^\/(?:[^\/]*\/){1}([^\/]*)\/(?:(\d{1,})|[^\/]*)\/.*?$
这是相同的表达式,但正斜率已被转义,因为某些语言需要
^
匹配行的开头/
匹配正斜杠(?:[^/]*/)
匹配一组文字后跟斜线,此组与未捕获的{1}
虽然在功能上与+
相同,但这使得开发人员能够通过简单地更改括号内的值来选择X个斜杠分隔字段来跳过([^/]*)
捕获非斜线字符串/
匹配斜杠(?:
启动非捕获组,这允许or
条件仅匹配包含的表达式(\d{1,})
捕获一组数字,虽然在功能上与+
相同但这使得开发人员能够通过简单地更改数字来选择必须存在的最小数字和最小数字。括号内的值|
或[^/]* match a group of text
)
非捕获组的结尾/
匹配下一个斜杠.*?$
匹配剩下的字符串,直到行尾。0接收整个匹配的字符串
我不是Ruby,所以我要包含一个php示例来证明表达式确实有效。
<?php
$sourcestring="/7/ipsum/dolor/etc
/2/not/17/ipsum/etc";
preg_match_all('/^\/(?:[^\/]*\/){1}([^\/]*)\/(?:(\d{1,})|[^\/]*)\/.*?$/im',$sourcestring,$matches);
echo "<pre>".print_r($matches,true);
?>
$matches Array:
(
[0] => Array
(
[0] => /7/ipsum/dolor/etc
[1] => /2/not/17/ipsum/etc
)
[1] => Array
(
[0] => ipsum
[1] => not
)
[2] => Array
(
[0] =>
[1] => 17
)
)