如何重复一个捕获组?

4

我有一个输入字符串,看起来像这样:

HLI6Ch60000Ch500C0Ch46400Ch30000Ch21888Ch10E79CS07LCU3Ch37880Ch27800Ch16480CS8CA00000000000000000000

现在我不关心最后一个字母A之后的部分,它总是A和20个对我没有用处的数字。然而,我确实需要最后一个字母A之前的部分,并且理想情况下,我需要将其分为两个不同的捕获组,就像这样:

1: HLI6Ch60000Ch500C0Ch46400Ch30000Ch21888Ch10E79CS07
2: LCU3Ch37880Ch27800Ch16480CS8C

唯一确定这些匹配项的方法是以字符CS结尾,后跟两个十六进制字符。我认为一个正则表达式,像(.+?CS.{2})+(或者(.+?CS[[:xdigit:]]{2})+)会做好工作,但是在www.regex101.com上尝试时,它只捕获最后一组,并给出以下警告: 注意: 重复捕获组只会捕获最后一次迭代。请在重复的组周围放置一个捕获组来捕获所有迭代,或者如果您不感兴趣数据,则改用非捕获组。
我认为这意味着我应该使用类似((.+?CS.{2})+)的正则表达式,我是说-当然,现在我得到了两个捕获,但它们看起来像这样:
1: HLI6Ch60000Ch500C0Ch46400Ch30000Ch21888Ch10E79CS07LCU3Ch37880Ch27800Ch16480CS8C
2: LCU3Ch37880Ch27800Ch16480CS8C

我的意思是第一个正则表达式稍微有点长了。如果有帮助的话,我应该指出最终的正则表达式将成为iOS应用程序的一部分,所以将使用NSRegularExpression类的实例 - 不确定这是否是有用的信息,只是我知道NSRegularExpression并不支持正则表达式世界的每个部分。


只需使用此正则表达式:(.+?CS.{2})(.+?CS.{2}),https://regex101.com/r/zD4cO2/1 - streetturtle
3个回答

4

哇,非常感谢!我...简直不敢相信我没想到那个。太简单了! - Cellane

2

看起来你根本不需要捕获组:

(?:(?!CS[0-9A-F]{2}).)+CS[0-9A-F]{2}

将匹配所有以CS + 2个十六进制数字结尾的字符串。

regex101.com上进行测试。

解释:

(?:                # Start a group.
 (?!CS[0-9A-F]{2}) # Make sure we can't match CSff here,
 .                 # if so, match any character.
)+                 # Do this at least once.
CS[0-9A-F]{2}      # Then match CSff.

感觉几乎就像魔法一样,太神奇了 - 谢谢,这也可以工作。 如果以后需要进行调整,我可能不得不诉诸于使用vks的解决方案(虽然我猜你的处理速度更快?),因为它更易读。 不过,非常感谢您的时间! - Cellane

1
将你的正则表达式改为:
(.+?CS[[:xdigit:]]{2})

演示

您不需要将正则表达式放在另一个捕获组中并使其重复一次或多次。只需打印组索引1即可获得所需的输出。


啊,该死,非常抱歉,我忘了提到在最终的 A.{20} 部分之前可能会有更多的 HLI6/LCU3 部分,而不仅仅是两个! - Cellane
@Cellane,你只说它以[:xdigit:]]{2}两个十六进制字符结尾。 - Avinash Raj
哦,对了,我又读错了。所以你的情况和vks的一样,已经点赞并非常感谢你的时间!我简直不敢相信我还没有尝试过这个。 - Cellane
@Cellane 注意,我是第一个发布这个正则表达式的人。您错误地接受了在我之后2分钟发布的答案。所以vks的答案和我的一样,而不是我的答案和vks的一样。 - Avinash Raj
哦!你说得完全正确,我不仅在阅读方面失败了,而且也没有注意到这一点。已经修复。 - Cellane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接