捕获多个字母

时间:2013-05-25 16:23:59

标签: regex reddit

所以,我要承认,我从未真正研究过正则表达式。我要做的是捕获Reddit URL的ID。网址格式将为/r/AskReddit/comments/1234/r/AskReddit/1234/或某些变体(缺少结束斜线) - 它不应与dsada/...中的/r/AskReddit/comments/1234/dsada/...

相匹配

这是我到目前为止所尝试的内容:

/r/.*/[comments/]?([a-z0-9])/?

它匹配一些奇怪的东西,

尝试匹配/r/sdifsas/sdfad时,它实际上会匹配/r/sdifsas/sd,它甚至会匹配/r/sdifsas/sdfad/aasdasd/a/r/sdifsas/comments/a/d

我知道事实上我做错了什么,我觉得它与.*有关,如何在仍然匹配所有内容的情况下替换.*?另外,如何使正则表达式捕获结尾字母中的多个(或上面的一些随机匹配中的两个)?

还有一件事,如果不是太麻烦,你能解释一下你用过的每件东西吗?我对此有点新手。

3 个答案:

答案 0 :(得分:1)

首先,在你的正则表达式中.*匹配所有内容直到字符串结束,然后开始回溯直到它成功。

其次,[...]匹配其中的任何字母,之后?给出了可选的含义。

因此,在/r/sdifsas/sd的测试用例中,.*/匹配到最后一个正斜杠,后面的字母是s里面[...]和最后d }}是a-z范围内的一个。

在您的测试中/r/sdifsas/sdfad/aasdasd/a类似,.*/匹配到最后一个正斜杠,a字母不在[...]内,所以跳过该部分并在范围内匹配a-z/r/sdifsas/comments/a/d的行为相同。

我不知道你正在使用什么样的正则表达式,但在黑暗中拍摄会是这样的:

/r/.*?/(?:comments/)?([a-z0-9]*)/? 

它为路径的该部分使用非捕获组(?:...),并使用*匹配字母和/或数字中的零或更多。

答案 1 :(得分:1)

描述

此正则表达式将通过要求/r/后跟subreddit的名称来验证字符串,然后它将移动并捕获id,前提是它出现在subreddit名称之后或注释之后。通过在搜索中使用m选项并包含^以匹配行的开头而$匹配行的结尾,此正则表达式可用于对齐长字符串包含任意数量的新行分隔的reddit链接的文本,如PHP示例中所示。

^\/r\/([a-z0-9]*)\/(?:Comments\/)?([a-z0-9]*)(?:\/?.*?)?$

enter image description here

0匹配整个字符串

  1. 捕获子reddit名称
  2. 捕获ID
  3. PHP代码示例:

    您没有指定语言,所以我选择了PHP来展示这个正则表达式是如何工作的。

    <?php
    $sourcestring="/r/AskReddit/comments/1234
    r/AskReddit/2345/
    /r/AskReddit/comments/3456/dsada/
    /r/IHeartKittens/comments/4567/dsada/
    /r/cats/comments/i2sz9/we_rescued_a_kitten_last_month/
    /r/IAmA/comments/18pik4/astronaut_chris_hadfield_comments/c8gud3h";
    preg_match_all('/^\/r\/([a-z0-9]*)\/(?:Comments\/)?([a-z0-9]*)(?:\/?.*?)?$/im',$sourcestring,$matches);
    echo "<pre>".print_r($matches,true);
    ?>
    
    
    $matches Array:
    (
        [0] => Array
            (
                [0] => /r/AskReddit/comments/1234
                [1] => /r/AskReddit/2345/
                [2] => /r/AskReddit/comments/3456/dsada/
                [3] => /r/IHeartKittens/comments/4567/dsada/
                [4] => /r/cats/comments/i2sz9/we_rescued_a_kitten_last_month/
                [5] => /r/IAmA/comments/18pik4/astronaut_chris_hadfield_comments/c8gud3h
            )
    
        [1] => Array
            (
                [0] => AskReddit
                [1] => AskReddit
                [2] => AskReddit
                [3] => IHeartKittens
                [4] => cats
                [5] => IAmA
            )
    
        [2] => Array
            (
                [0] => 1234
                [1] => 2345
                [2] => 3456
                [3] => 4567
                [4] => i2sz9
                [5] => 18pik4
            )
    
    )
    

答案 2 :(得分:0)

尝试

/r/AskReddit/[comments/]?([a-z0-9])/?

代替。

您的解决方案存在两个缺陷:

  1. 您的.*部分与所有内容相匹配 - 特别是构成网址位置部分的/个字符
  2. 你贪婪地匹配,这是大多数正则表达式引擎的默认值。 “贪婪”意味着在一场比赛中,子模式吞噬了尽可能多的字符。
  3. 1&amp; 2密谋匹配网址中比你想要的更大的portioins。