Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.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
Regex 如何捕获多个重复组?_Regex_Swift_Nsregularexpression_Regex Greedy_Regex Group - Fatal编程技术网

Regex 如何捕获多个重复组?

Regex 如何捕获多个重复组?,regex,swift,nsregularexpression,regex-greedy,regex-group,Regex,Swift,Nsregularexpression,Regex Greedy,Regex Group,我需要捕获相同模式的多个组。假设我有以下字符串: HELLO,THERE,WORLD 我写了下面的模式 ^(?:([A-Z]+),?)+$ 我想让它做的是,捕捉每一个单词,第一组是:“你好”,第二组是“那里”,第三组是“世界”,我的正则表达式实际上只捕捉最后一个单词,即“世界” 我正在测试我的正则表达式,我想将它与Swift一起使用(也许Swift中有一种方法可以以某种方式获得中间结果,这样我就可以使用它们了?) 更新:我不想使用split。我现在只需要了解如何捕获与模式匹配的所有组,而不仅

我需要捕获相同模式的多个组。假设我有以下字符串:

HELLO,THERE,WORLD
我写了下面的模式

^(?:([A-Z]+),?)+$
我想让它做的是,捕捉每一个单词,第一组是:“你好”,第二组是“那里”,第三组是“世界”,我的正则表达式实际上只捕捉最后一个单词,即“世界”

我正在测试我的正则表达式,我想将它与Swift一起使用(也许Swift中有一种方法可以以某种方式获得中间结果,这样我就可以使用它们了?)


更新:我不想使用
split
。我现在只需要了解如何捕获与模式匹配的所有组,而不仅仅是最后一组。

模式中有一组,您只能在该组中获得一个精确结果。如果您的捕获组被模式重复(您在周围的非捕获组上使用了
+
量词),则只存储与之匹配的最后一个值

必须使用语言的正则表达式实现函数来查找模式的所有匹配项,然后必须删除非捕获组的锚和量词(也可以省略非捕获组本身)

或者,展开您的正则表达式,并让模式包含每个要在结果中获得的组的一个捕获组:

^([A-Z]+),([A-Z]+),([A-Z]+)$

仅提供答案中第2段的附加示例。我不确定对你来说,在一场比赛中获得三个小组比在一个小组中获得三场比赛有多重要。例如,在groovy中:

def subject = "HELLO,THERE,WORLD"
def pat = "([A-Z]+)"
def m = (subject =~ pat)
m.eachWithIndex{ g,i ->
  println "Match #$i: ${g[1]}"
}

Match #0: HELLO
Match #1: THERE
Match #2: WORLD

我想你需要这样的东西

b="HELLO,THERE,WORLD"
re.findall('[\w]+',b)
Python3中的哪个将返回

['HELLO', 'THERE', 'WORLD']
阅读之后,我想介绍一个可能的微小改进:

您可以生成与
n
单词匹配的regexp,只要您的
n
是预先确定的。例如,如果我想匹配1到3个单词,regexp:

([A-Z]+)(?:,([A-Z]+)(?:,([A-Z]+))(?:,([A-Z]+)$ 将下列句子与一组、两组或三组进行匹配

HELLO,LITTLE,WORLD
HELLO,WORLD
HELLO
您可以看到有关此正则表达式的详细说明

正如我所说的,使用您喜欢的语言为您想要的任何组生成这个regexp非常容易。由于我不是一个敏捷的人,这里有一个ruby示例:

def make_regexp(组_regexp,计数:3,分隔符:“,”)
regexp_str=“^(#{group_regexp})”
(计数-1)次。每次
regexp_str+=“(?:#{delimiter}(#{group_regexp}))”
结束
regexp_str+=“$”
返回regexp_str
结束
放置make_regexp(“[A-Z]+”)


话虽如此,我还是建议不要使用正则表达式。在这种情况下,还有许多其他很棒的工具,从简单的
拆分
,到一些标记化模式,都取决于您的需要。嗯,正则表达式不是其中之一。例如,在ruby中,我会使用类似于
str.split(“,”)
str.scan(/[A-Z]+/)

的东西,我知道我的答案来得晚,但今天我遇到了,我用以下方法解决了它:

^(([A-Z]+),)+([A-Z]+)$

因此,第一组
([A-Z]+),)+
将匹配所有重复的模式,但最后一组
([A-Z]+)
将匹配最后一组。无论字符串中有多少重复的组,这都是动态的。

您实际上有一个捕获组将匹配多次。不是多个捕获组

javascript(js)解决方案:

let string=“你好,汤姆”;
设myRegexp=/([A-Z]+),?/g;//随意修改
让match=myRegexp.exec(字符串);//js函数,输出如下所述
while(match!=null){//在匹配中循环
console.log(match[1]);//对每个匹配执行任何操作
match=myRegexp.exec(字符串);//查找下一个匹配项

}
对不起,不是Swift,只是用最接近的语言证明概念

// JavaScript POC. Output:
// Matches:  ["GOODBYE","CRUEL","WORLD","IM","LEAVING","U","TODAY"]

let str = `GOODBYE,CRUEL,WORLD,IM,LEAVING,U,TODAY`
let matches = [];

function recurse(str, matches) {
    let regex = /^((,?([A-Z]+))+)$/gm
    let m
    while ((m = regex.exec(str)) !== null) {
        matches.unshift(m[3])
        return str.replace(m[2], '')
    }
    return "bzzt!"
}

while ((str = recurse(str, matches)) != "bzzt!") ;
console.log("Matches: ", JSON.stringify(matches))

注意:如果您真的要使用此选项,您将使用regex match函数给出的匹配位置,而不是字符串替换。

关键区别在于重复捕获的组,而不是捕获重复的组


正如您已经发现的,不同之处在于重复捕获的组只捕获最后一次迭代。捕获重复的组将捕获所有迭代

在PCRE(PHP)中:

由于所有捕获都在组1中,因此您只需要
$1
进行替换

我使用了此正则表达式的以下一般形式:

(((?:{{RE}})+)
举例

  • 设计一个与列表的每个特定元素相匹配的正则表达式,而不是将列表作为一个整体。使用/g应用它
  • 循环遍历匹配项,从任何垃圾中清除它们,例如混合在其中的列表分隔符。您可能需要另一个正则表达式,也可以使用简单的替换子字符串方法
  • 示例代码是JS,抱歉:)这个想法必须足够清楚

        const string = 'HELLO,THERE,WORLD';
    
        // First use following regex matches each of the list items separately:
        const captureListElement = /^[^,]+|,\w+/g;
        const matches = string.match(captureListElement);
    
        // Some of the matches may include the separator, so we have to clean them:
        const cleanMatches = matches.map(match => match.replace(',',''));
    
        console.log(cleanMatches);
    

    为什么不在
    上拆分?为什么不使用
    [A-Z]+
    [^,]+
    来捕获结果Rock321987,我已经更新了输入字符串。我需要精确地提取遵循上述模式的字符串。我需要让所有的组都符合模式,而不仅仅是最后一组。我想知道如何处理regex.rock321987,还有什么不清楚的?我需要字符串中的每个单词都是匹配的组,但我的模式只捕获最后一个(“世界”)。使用此模式查找所有匹配项如何调整此值以考虑不同数量的字符串?e、 你好,世界,你好,我的世界。我正在寻找一个表达式来处理这两个示例,并为更长的字符串提供内置的灵活性arrays@Chris这是不可能一概而论的。正如答案所述,一个捕获组只能捕获一件事情,并且无法创建动态数量的捕获组。这不是问题的解决方案。问题不是匹配字符串,而是捕获所有组。T
    Match 1, Group 1.    0-5      HELLO
    Match 2, Group 1.    6-11     THERE
    Match 3, Group 1.    12-20    BRUTALLY
    Match 4, Group 1.    21-26    CRUEL
    Match 5, Group 1.    27-32    WORLD
    
        const string = 'HELLO,THERE,WORLD';
    
        // First use following regex matches each of the list items separately:
        const captureListElement = /^[^,]+|,\w+/g;
        const matches = string.match(captureListElement);
    
        // Some of the matches may include the separator, so we have to clean them:
        const cleanMatches = matches.map(match => match.replace(',',''));
    
        console.log(cleanMatches);