首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python-re中的regex条件提取

python-re中的regex条件提取
EN

Stack Overflow用户
提问于 2022-05-30 14:21:26
回答 2查看 60关注 0票数 0

我正在尝试从错误文本中提取SQLCODE,它通常是4个整数,如下所示:

代码语言:javascript
复制
1. SQLSTATE: 22018, SQLCODE: 3535.
2. SQLSTATE: 40001, SQLCODE: 2631 Session Id           629709103
3. SQLSTATE: 40001, SQLCODE: 2631                Session Id  594700603
4. SQLSTATE: T7547, SQLCODE:   754Session Id613234380

我有下面的模式匹配正则表达式的相同目前。然而,有一个像4这样的边缘情况正在失败。

代码语言:javascript
复制
error_cd = re.findall(r'SQLCODE:\s([^.,\s]+)', err_log)

如果SQLCODE之后没有4个整数,我想在字母'T‘之后提取SQLSTATE文本

预期产出:

代码语言:javascript
复制
1. 3535
2. 2631
3. 2631
4. 7547

任何关于如何实现这一目标的建议都将受到赞赏。谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-05-30 14:30:17

这可能完全可以在regex中完成,使用查找/后置来处理条件提取,但这可能会变得非常混乱。

解决方案1:纯Regex:

编辑:这是纯正则表达式.比我想象的更简单(虽然肯定比混合方法更容易出错……需要一些额外的逻辑才能使其更加健壮):

代码语言:javascript
复制
re.findall(r'((?:(?<=SQLSTATE: T)(?![0-9]{4}, SQLCODE: [0-9]{4})[0-9]{4})|(?:(?<=SQLCODE: )[0-9]{4}))', err_log)

解决方案2: Regex和

以下解决方案使用regex同时提取SQLSTATE和SQLCODE值,并使用列表理解来执行条件提取:

代码语言:javascript
复制
err_log = '''
1. SQLSTATE: 22018, SQLCODE: 3535.
2. SQLSTATE: 40001, SQLCODE: 2631 Session Id           629709103
3. SQLSTATE: 40001, SQLCODE: 2631                Session Id  594700603
4. SQLSTATE: T7547, SQLCODE:   754Session Id613234380
'''

error_st_cd = re.findall(r'SQLSTATE: +T([0-9]+), SQLCODE: +([0-9]{4})?', err_log)
error_cd = [codes[1] or codes[0] for codes in error_st_cd]

for i, cd in enumerate(error_cd):
    print(f'{i+1}. {cd}')

输出:

  1. 3535
  2. 2631
  3. 2631
  4. 7547
票数 3
EN

Stack Overflow用户

发布于 2022-05-30 14:33:14

regex方法可能确实更容易,但无论如何,下面是regex的w/o方法:

代码语言:javascript
复制
test_string = """
1. SQLSTATE: 22018, SQLCODE: 3535.
2. SQLSTATE: 40001, SQLCODE: 2631 Session Id           629709103
3. SQLSTATE: 40001, SQLCODE: 2631                Session Id  594700603
4. SQLSTATE: T7547, SQLCODE:   754Session Id613234380
""".strip()


def process_lines(s: str):
    for line in s.split('\n'):
        sql_code = ''.join(take_nums(line.split('SQLCODE: ', 1)[-1]))
        if len(sql_code) == 4:
            yield sql_code
        else:
            sql_state = ''.join(take_nums(line.split('SQLSTATE: ', 1)[-1][1:]))
            yield sql_state


def take_nums(s: str):
    """take from string only while we get space or numeric chars"""
    for c in s:
        if c.isnumeric():
            yield c
        elif not c.isspace():
            break


for i, line in enumerate(process_lines(test_string), 1):
    print(f'{i}. {line!r}')

结果:

代码语言:javascript
复制
1. '3535'
2. '2631'
3. '2631'
4. '7547'
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72435864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档