这可能是一个新手问题,但是如何有效地在字符串上应用正则表达式来检索字符串的一部分?作为一个例子,我有一个具体的解析来解决。
如果我有字符串:
STRING[(val1)-{val2}-!val3!]
或
STRING[{val2}-!val3!-(val1)]
或
STRING[!val3!-(val1)-{val2}]
等......(我不会打扰你的所有8个!val3!,(val2),{val1}的排列。)
我可以做几个简单的发现和分裂来达到我的目的,但你怎么能以干净和安全的方式做事情来得到类似的东西:
val1,val2,val3 = ...
?
更新:在要解析的字符串中,val1
,val2
和val3
是可变输入,以及三个分隔符!! (){}是帮助我知道每个具有另一个语义含义的三个值在哪里。
答案 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('-')