2

这里是正则表达式的新手,我将不胜感激。

cstring = "[0,90,(+45,45)3,0/]S"
regex = re.compile(r'^(\[)(\S+)(\/?)(\][ST]$)')
match = regex.search(cstring)
for s in match.groups():
    print s

结果是 "[" "0,90,(+45,45)3,0/" "]S" 但我想在一个单独的(和可选的 - 上面唯一的一个)组中获得 "/" . 我试图用 [0-9(),+-] 之类的任何组合替换 \S - (这些是第二组中唯一预期的字符)但无济于事。

4

2 回答 2

4

正则表达式数量说明符 + 和 * 是贪心的,您可以添加 ? 到它们的末尾(+?和*?)将它们变成它们的非贪婪形式。

贪婪意味着操作员将在检查下一个令牌之前尝试消耗所有可能的东西。

所以对于

\S+\/?

S 将在 / 被检查之前尝试使用它可以使用的所有内容,并且由于 / 是可选的,因此无需为它做任何事情。

一旦我们把它变成非贪婪的形式

\S+?\/?

在尝试 / 之前,S 将尽可能少地消耗,这意味着 / 在任何令牌上获得“第一个 dibs”,一旦它无法抓住它们,这些令牌将针对 \S+?

我使用以下方法找到了成功:

regex = re.compile(r'^(\[)(\S+?)(\/?)(\][ST]$)')

有关更多信息,您可以查看python re docs search for greedy。

作为旁注,如果您将 re.VERBOSE 标志传递给 re.compile 那么它将忽略字符串中的空格,这意味着您可以将其构造为

regex = re.compile(r'^ (\[) (\S+?) (\/?) (\][ST]$) ', re.VERBOSE)

我发现在学习正则表达式时很有帮助。

此外,您在组 '^ ([' 之外有字符串标记的开头,但在组 '(][ST]$)' 内有字符串标记的结尾,除了可读性之外,这应该没有什么区别。

于 2012-06-03T03:18:39.933 回答
0

\S尝试对你的角色使用非贪婪匹配。那群人正在吞噬你的/角色。

将您的正则表达式更改为此对我有用:

cstring = "[0,90,(+45,45)3,0/]S"
regex = re.compile(r'^(\[)(\S+?)(\/?)(\][ST]$)')
match = regex.search(cstring)
for s in match.groups():
    print s
于 2012-06-03T03:18:50.890 回答