为多个字符串编译Python正则表达式

2024-06-25 23:06:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在数据下面实现一个模式。在

-----------------------------------------------
| COLUMN_NAME          | DATA_TYPE            |
-----------------------------------------------
| C460                 | VARCHAR2             |
| C459                 | CLOB                 |
| C458                 | VARCHAR2             |
| C8                   | BLOB                 |
| C60901               | INT                  |

我可以创建pattern来选择COLUMN_NAME,其中CLOB,BLOB匹配,但我也需要INT数据类型的COLUMN_NAME。 在这种情况下,我应该得到C459,C8,C60901。在

使用下面的代码,我只得到C60901,因为我使用了|,它只不过是OR,但我想要CLOBINTC459,C8,C60901的{}

^{pr2}$

我已经从这个文档中得到了帮助Regx documentation,但我找不到可靠的答案。在


Tags: 数据namedatatype模式columnblobint
2条回答

我假设您只想获取列\u NAME中的值,其中DATA_TYPE为CLOB或INT。这将为您提供以下列表:

>>> text="""                       -
| COLUMN_NAME          | DATA_TYPE            |
                       -
| C460                 | VARCHAR2             |
| C459                 | CLOB                 |
| C458                 | VARCHAR2             |
| C8                   | BLOB                 |
| C60901               | INT                  |"""
>>> import re
>>> re.findall(re.compile("\| (\S+)\s*\| (?:CLOB|INT).*"),text)
['C459', 'C60901']

这在python3.5.2上适用

Python的re-module中有一个我非常喜欢的VERBOSE选项。代码应该是自解释的(根据3.6检查)

import re

data = """
                       -
| COLUMN_NAME          | DATA_TYPE            |
                       -
| C460                 | VARCHAR2             |
| C459                 | CLOB                 |
| C458                 | VARCHAR2             |
| C8                   | BLOB                 |
| C60901               | INT                  |
"""

pattern = """
(C\d+)             # Match a capital C followed by at least one digit
(?:\s*\|\s)        # Non-matching group for \s - whitespace, \| - pipe, \s - whitespace
(?=INT|CLOB|BLOB)  # Positive Lookahead match INT, CLOB or BLOB
"""
match_column = re.compile(pattern, re.VERBOSE)
columns = match_column.findall(data)
print(list(columns))

这应该会给你['C459','C8','C60901',这就是你所追求的。一旦你明白了你可以写:r'(C\d+)(?:.*(?:INT|CLOB|BLOB))'。但是,对于冗长和特定的匹配(空白和管道字符),有一些事情可以说,滥用.常常会导致正则表达式匹配超出我最疯狂梦想的东西。在

你真的不应该做以上任何事!伟大的黑客杰米·扎文斯基曾经说过:

Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.

如果您能够逐行处理输入,我会这样做:

^{pr2}$

相关问题 更多 >