应用正则表达式来检索字符串

时间:2011-12-12 09:36:23

标签: python regex

这可能是一个新手问题,但是如何有效地在字符串上应用正则表达式来检索字符串的一部分?作为一个例子,我有一个具体的解析来解决。

如果我有字符串:

STRING[(val1)-{val2}-!val3!]

STRING[{val2}-!val3!-(val1)]

STRING[!val3!-(val1)-{val2}]

等......(我不会打扰你的所有8个!val3!,(val2),{val1}的排列。)

我可以做几个简单的发现和分裂来达到我的目的,但你怎么能以干净和安全的方式做事情来得到类似的东西:

val1,val2,val3 = ...

更新:在要解析的字符串中,val1val2val3是可变输入,以及三个分隔符!! (){}是帮助我知道每个具有另一个语义含义的三个值在哪里。

6 个答案:

答案 0 :(得分:4)

您可以使用lookahead assertions与捕获组按任意顺序查找匹配项:

import re
def matchany(subject):
    match = re.match(
        r"""
        (?=.*\(([^()]*)\))   # Find match between () --> group 1
        (?=.*\{([^{}]*)\})   # Find match between {} --> group 2
        (?=.*!([^!]*)!)      # Find match between !! --> group 3""", 
        subject, re.VERBOSE)
    return match.groups() if match else None

然后你可以做

>>> matchany("STRING[(val1)-{val2}-!val3!]")
('val1', 'val2', 'val3')
>>> matchany("STRING[!val3!-(val1)-{val2}]")
('val1', 'val2', 'val3')
>>> matchany("STRING[(val1)-{val2}-!val3]")
>>>

答案 1 :(得分:1)

要获得真正完整的答案,您应该进一步说明可能的输入字符串是什么,以及要匹配的字符串的格式是什么。然而,这是一个示例,至少说明了re.findall

的基本匹配机制
>>> examples = '''STRING[(val1)-{val2}-!val3!]
... STRING[{val2}-!val3!-(val1)]
... STRING[!val3!-(val1)-{val2}]
... '''
>>> for line in examples.split('\n'):
...     print re.findall(r'val\d', 'STRING[(val1)-{val2}-!val3!]')
... 
['val1', 'val2', 'val3']
['val1', 'val2', 'val3']
['val1', 'val2', 'val3']
['val1', 'val2', 'val3']

编辑:正则表达式r'val\d'指示匹配由字母val +一个,只有一个数字形成的所有位。

HTH!

答案 2 :(得分:1)

你真的需要正则表达式吗?根据您的输入, - 看起来像一个分隔符:

>>> s = "STRING[(val1)-{val2}-!val3!]"

# First step, remove the "STRING[" + "]" from the source string
>>> s = s[7:-1]
>>> print s
(val1)-{val2}-!val3!

# Then, split on the '-', and remove the first/last char (mean []!! etc..)
# Work with any other values if they don't have '-' in it
>>> [x[1:-1] for x in s.split('-')]
['val1', 'val2', 'val3']

答案 3 :(得分:1)

import re

regx = re.compile('(?<=[\[-])[!({](.+?)[!)}](?=[\]-])')

for ss  in ('STRING[(val1)-{val2}-!val3!]',
            'STRING[{val2}-!val3!-(val1)]',
            'STRING[!val3!-(val1)-{val2}]',
            'STRING[!val3!-!val1!-{val2}]'):
    print regx.findall(ss)

结果

['val1', 'val2', 'val3']
['val2', 'val3', 'val1']
['val3', 'val1', 'val2']
['val3', 'val1', 'val2']

但是被剥削的字符串必须严格遵守模式:没有空格,没有一个字符! ({})后跟或前面有[或 - 在所需的值中(如果不是这样,则在我的模式中断言,正确处理案例)等等 如有必要,可以改进正则表达式模式

修改

我改进了模式,以便在值前面加上'!' ,以'!'结尾 如果前面有'(',以''结尾'),则 如果以'{'开头,则以'}'结尾

import re

regx_1 = re.compile('(?<=[\[-])'
                    '[!({]'
                    '(.+?)'
                    '[!)}]'
                    '(?=[\]-])')

regx_2 = re.compile('(?<=[\[-])'
                    '(?:'
                        '(!)'
                        '|'
                        '(\()'
                        '|'
                        '(\{)'
                    ')'
                    '(.+?)'
                    '(?(1)!|(?(2)\)|(?(3)\})))'
                    '(?=[\]\-])'
                    )

for ss  in ('STRING[(val1)-{val2}-!val3!]',
            'STRING[{val2}-!val3!-(val1)]',
            'STRING[!val3!-(val1)-{val2}]',
            'STRING[!val3!-!val1!-{val2}]',
            'STRING[!va}-l3!-!val)-1!-{va!-)-l2}]',):
    print ('------------------------------\n'
           '%s\n\n%s\n\n%s\n%s\n') % (ss,
                                      regx_1.findall(ss),
                                      regx_2.findall(ss),
                                      [ x[3] for x in regx_2.findall(ss)])

结果

------------------------------
STRING[(val1)-{val2}-!val3!]

['val1', 'val2', 'val3']

[('', '(', '', 'val1'), ('', '', '{', 'val2'), ('!', '', '', 'val3')]
['val1', 'val2', 'val3']

------------------------------
STRING[{val2}-!val3!-(val1)]

['val2', 'val3', 'val1']

[('', '', '{', 'val2'), ('!', '', '', 'val3'), ('', '(', '', 'val1')]
['val2', 'val3', 'val1']

------------------------------
STRING[!val3!-(val1)-{val2}]

['val3', 'val1', 'val2']

[('!', '', '', 'val3'), ('', '(', '', 'val1'), ('', '', '{', 'val2')]
['val3', 'val1', 'val2']

------------------------------
STRING[!val3!-!val1!-{val2}]

['val3', 'val1', 'val2']

[('!', '', '', 'val3'), ('!', '', '', 'val1'), ('', '', '{', 'val2')]
['val3', 'val1', 'val2']

------------------------------
STRING[!va}-l3!-!val)-1!-{va!-)-l2}]

['va', 'val', 'va']

[('!', '', '', 'va}-l3'), ('!', '', '', 'val)-1'), ('', '', '{', 'va!-)-l2')]
['va}-l3', 'val)-1', 'va!-)-l2']

答案 4 :(得分:1)

使用&#34; val1&#34;,&#34; val2&#34;,&#34; val3&#34;将您的字符串解析为字典作为键和找到的字符串作为对应的值,您可以使用某些内容作为下面的代码片段。

import re

examples = '''STRING[!hello!-(world)-{zup}]
STRING[{foobar}-!stack!-(overflow)]
STRING[(this)-{might}-!work!]''';

name_dict = {
  '(': 'val1',
  '{': 'val2',
  '!': 'val3'
}

for testcase in examples.split ('\n'):
  result = {}

  for x in re.split ('[!)}]-', testcase[7:-2]):
    result[name_dict[x[0]]] = x[1:]

  print result

输出

{'val3': 'hello', 'val2': 'zup', 'val1': 'world'}
{'val3': 'stack', 'val2': 'foobar', 'val1': 'overflow'}
{'val3': 'work', 'val2': 'might', 'val1': 'this'}

答案 5 :(得分:0)

带有正则表达式。

如果您的值包含用于形成值结束帧'!','}'或')'的任何字符,则此示例不起作用:

import re
s = 'your string here'
val1, val2, val3 = re.sub(r'[!{(](?P<value>.+?)[!})](?P<delimiter>-)?', '\g<value>\g<delimiter>', s).split('-')