如何从正则表达式捕获组中修剪空白?

Posted

技术标签:

【中文标题】如何从正则表达式捕获组中修剪空白?【英文标题】:How can whitespace be trimmed from a Regex capture group? 【发布时间】:2013-02-01 02:58:37 【问题描述】:

正在检查的字符串类似于以下内容(注意括号之间的空格):

[name]  [address ] [ zip] [ phone number ]

我目前使用的表达方式...

\[([^\])]*)\]

...成功地捕获了括号内的每个文本,但它也捕获了前导和尾随空格,所以我最终得到:

"name"  "address "  " zip"  " phone number "

但我寻求的是:

"name"  "address"  "zip"  "phone number"

如何说服正则表达式不捕获这些示例中的空格? (除了嵌入的空格 - 例如“电话号码”中的单词之间的空格。)

(注意:我知道我可以从捕获的变量中修剪它表达式完成后,但我试图在的上下文中进行表达式。)

感谢您的任何想法!下面是我用来测试的确切代码:

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\[([^\\])]*)\\]" options:0 error:nil];

NSString *string = @" [name] [address ] [ zip] [ phone number ] ";

NSString *modifiedString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length])
    withTemplate:@"\n\n[$1]"]; //note: adding brackets back here just to make it easy to see if the space has been trimmed properly from the captured value

NSLog(@"\n\n%@", modifiedString);

【问题讨论】:

【参考方案1】:

我会一步一步来的。

首先,([^\])]*) 不正确。这意味着“0 个或多个字符的序列,尽可能长,不包含 ] 或 )。”

例如,对于这个表达式:

 [name] [address ) ] [ zip] [ phone number ] 

...地址部分将被跳过,因为“地址)”不匹配[^\)]]*(这意味着“零个或多个字符的序列,不包括)和]。”

我们想要([^\]]*),它不会跳过)。

接下来,我们想吃掉捕获周围的所有空间。为此,我们使用两个 * 序列,在捕获的每一侧都有一个:

\[ *([^\]]*) *\]

现在我们需要变得棘手! [^\]]* 默认是贪婪的。这意味着任何一方的一些空间可能会被它匹配,因此包含在捕获中!我们想改用非贪婪版本[^\]]*?。这意味着“一个包含 0 个或多个字符的序列,不包含 ],尽可能短,同时符合正则表达式的其余部分。”

\[ *([^\]]*?) *\]

【讨论】:

这对我来说是一个有趣的问题,因为我多年来一直在编写正则表达式和 Objective-C,但我之前从未使用过NSRegularExpression 将它们结合起来。 :) 谢谢你这是完美的!如果您是 NSRegularExpression 的新手,请查看它的“enumerateMatchesInString:options:range:usingBlock:”方法,了解一些块状的优点:blog.kvnd.me/post/10186864667/regular-expressions-in-ios 根据这次谈话,我重写了我的答案。我认为这将为未来的读者提供更好的服务,逐步完成从您提供的内容到最终答案的转变。怎么样? 您是否缺少“?”在更新解释的最后一段中的非贪婪 sn-p 中?顺便说一句,很好的解释! 确实,很棒的收获。正则表达式是密集的小东西,不是吗?【参考方案2】:
@"\\[\\s*([^\\]]+?)\\s*\\]"

@"\\[ *([^\\]]+?) *\\]"

上面的空格要小心输入。

这不会捕获空格: NSLog 输出 [名称] [地址] [邮编] [电话号码]

“?”使前面的元字符非贪婪,贪婪是默认值。

【讨论】:

以上是关于如何从正则表达式捕获组中修剪空白?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用正则表达式验证捕获组中的最后一个字符

正则表达式修剪空白

正则表达式中 如何取出所有组中的值?

哪个更快?修剪()或正则表达式?

如何在正则表达式组中返回 None? [复制]

正则表达式将字符串中的值捕获到一个组中,而不考虑顺序?