我是Python正则表达式的非常基本的用户,需要一些专家建议
使用正则表达式解决问题。

我正在尝试使用以下规则从字符串中提取一些信息。


以$(
启动标签后必须有一个单词。
(可选)在其后的单词中可能包含

除'和'[如果不成对使用,则不包括任何其他字符]到结尾字符为止)
仅当使用\进行转义时,才允许使用'和'[如果不是成对使用,则单独使用]
如果包含在“或”中,甚至可以允许)。

以)结尾


作为解决方案,如果允许以某种方式在字符集[]中定义和使用特殊类型的字符,将很容易。

例如:

re.compile("""\$\((\w*)
              [(any characters except ' and " [if used singly not in pairs] )
               (' and " [if used singly not in pairs] are allowed only if escaped using a \)
               ( even ) if enclosed within '' or "")
              ]\)""", re.VERBOSE)


一些测试:


$(listInput)这条尾巴-> listInput
$(listInput:DS)这条尾巴-> listInput:DS
$(listInput:J =“)”:S = .o)尾-> listInput:J =“)”:S = .o
$(listInput:J = join \'with)尾-> listInput:J = join'with


是否可以在Python中执行类似的操作,或者我的解决方案不是Pythonic?
还建议,是否有更好的解决方案。

谢谢

最佳答案

这个似乎可以满足您的要求:

^\$\((\w(?:\w|[^)\\"']|"[^"]*"|'[^']*'|\\"|\\')*)\)


分解:

^                   # start of string
\$\(                # "$("
(                   # start group 1
  \w                  # a word character
  (?:                 # start non-capturing group, one of:
    \w                  # a word character
    |                   # or
    [^)\\"']            # anything except ")" and special characters
    |                   # or
    "[^"]*"             # a double-quoted section
    |                   # or
    '[^']*'             # a single-quoted section
    |                   # or
    \\"                 # a backslash-escaped double quote
    |                   # or
    \\'                 # a backslash-escaped single quote
  )*                  # end group, repeat
)                   # end group 1
\)                  # ")"


就像您的示例所要求的一样。

缺点:


在没有更好的“单词”规范的情况下,我使用了\w。熟悉\w的匹配项,并在需要时使用更具体的内容。
不允许引用嵌套。 (这是Python正则表达式无法做到的)
它在引号中的结束引号之上运行。需要更多信息才能正确使用此功能。
带引号的部分中没有转义的引号(尽管可以添加)


测试:

regex = re.compile("^\$\((\w(?:\w|[^)\\\"']|\"[^\"]*\"|'[^']*'|\\\"|\\')*)\)")
string = "$(listInput:J=join\'with) tail"

r = regex.search(string)

r.groups()
# -> (u"listInput:J=join\\'with",)

regex.findall(string)
# -> [u"listInput:J=join\\'with"]

10-06 13:18