3

我有如下所示的 URI 字符串(etc可以是任意长度):

/7/ipsum/dolor/etc
/2/not/17/ipsum/etc

这是我想要实现的目标:在正斜杠上拆分字符串,获取第二个和第三个匹配项(["ipsum", "dolor"]["not", "17"]),如果第二个元素不是数字,则丢弃它。期望的结果是["ipsum"]["not", "17"]

我用纯红宝石实现了这一点(通过将字符串拆分为一个数组,然后检查所需值的值)。有没有更好的方法来用正则表达式做到这一点?

4

2 回答 2

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"]
于 2013-05-26T21:01:05.830 回答
2

描述

此表达式将返回第二个值,如果是数字则返回第三个值。

^/(?:[^/]*/){1}([^/]*)/(?:(\d{1,})|[^/]*)/.*?$

^\/(?:[^\/]*\/){1}([^\/]*)\/(?:(\d{1,})|[^\/]*)\/.*?$这是相同的表达式,但是正斜杠已被转义,因为某些语言需要

在此处输入图像描述

  • ^匹配一行的开头
  • /匹配正斜杠
  • (?:[^/]*/)匹配一组文本后跟一个斜线,该组匹配一个未捕获的
  • {1}尽管在功能上与此相同,+但开发人员能够通过简单地更改括号内的值来选择要跳过的 X 个斜线分隔字段
  • ([^/]*)捕获非斜线字符串
  • /匹配斜线
  • (?:启动一个非捕获组,这允许or条件只匹配包含的表达式
  • (\d{1,})捕获一组数字,尽管在功能上与此相同,但+开发人员能够选择最小和如果需要的最大数字数,这些数字必须通过简单地更改括号内的值来呈现
  • |或者
  • [^/]* match a group of text )非捕获组结束
  • /匹配下一个斜线
  • .*?$匹配剩余的字符串直到行尾。

团体

0 接收整个匹配的字符串

  1. 接收第二个值
  2. 接收第三个值,只要它是一个数字

免责声明

我不是 Ruby,所以我包含了一个 php 示例来证明该表达式确实有效。

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
        )

)
于 2013-05-26T22:04:01.580 回答