正则表达式从字符串中提取特定文本[重复]
Posted
技术标签:
【中文标题】正则表达式从字符串中提取特定文本[重复]【英文标题】:Regular Expression to extract specific text from string [duplicate] 【发布时间】:2019-08-15 07:32:46 【问题描述】:我是 Regex 的新手,我尝试从字符串列表中提取 16 倍字符的文本。
示例列表:
myString = [' pon-3-1 | UnReg 5A594F4380661123 1234567890 Active',
' pon-3-1 | UnReg 5A594F43805FA456 1234567890 Active',
' pon-3-1 | UnReg 4244434D73B24789 1234567890 Active',
' pon-3-1 | UnReg 5A594F43805FB000 1234567890 Active',
'sw-frombananaramatoyourmama-01'
]
我不能使用像 (\w16) 这样的简单正则表达式,因为这将包含所有 16 个字符的文本。 我还尝试了 (\w+A) ,根据字符串中的字符,它不会返回正确的结果。
newArry = []
for i in myString:
number = re.search('(\w16)', i)
newArr.append(number[0])
print(newArr)
返回:
['5A594F4380661123', '5A594F43805FA456', '4244434D73B24789', '5A594F43805FB000', 'frombananaramato']
-
我只想提取:
5A594F4380661123
5A594F43805FA456
4244434D73B24789
5A594F43805FB000
有什么想法吗?
在此先感谢
【问题讨论】:
那么,you 如何将那些特定的 16 字符子字符串与其他子字符串区分开来?例如,如果它们总是大写,请使用该事实。您还可以查看单词边界,正则表达式支持。 ...通缉的似乎也被封闭在空格中...re.findall(r'UnReg\s(.16)', ' '.join(myString))
@jonrsharpe 是的,没错。总是大写。不过请注意,我是 Regex 的新手,还不知道如何将数字与字母和大写字母结合起来。
然后参见例如***.com/questions/4736/learning-regular-expressions
【参考方案1】:
如果您想确保 16 个字符被非字母包围,请尝试
re.search(r'\b([0-9A-F]16)\b', i)
\b
“单词边界”运算符匹配一个位置,该位置一侧被字母包围,另一侧被非字母包围。
(如果您想更具体地确定哪些非字母,您可以使用环视:
re.search(r'(?<![0-9A-F])([0-9A-F]16)(?![0-9A-F])', i)
(?<!...)
表示 “前面不能有 ...”,(?!...)
表示 “后面不能有 ...”。)
您还会注意到,我将字符类收紧为仅匹配十六进制数字,这本身已经足以解决您的示例问题,并为正则表达式使用了 r'...'
原始字符串,您可能应该总是这样做(至少在你完全理解 Python 非原始字符串中的反斜杠是如何被破坏之前)。
【讨论】:
哇!这是令人印象深刻的感谢。两种解决方案都可以完美运行。我还测试了@בנימין כהן sn-p,它运行良好。如果要比较他和您的第一个 sn-p,我假设您的 sn-ps 提供了对字符串的更严格和准确的搜索?还是它们只是实现相同结果的 2 倍不同的方式。 另一个答案不限制匹配的上下文,所以它仍然会选择前 16 个例如20 个字符的字符串。使用边界标记,您不会匹配较长的十六进制字符串的子字符串。【参考方案2】:使用正则表达式集
number = re.search("([\dABCDEF]16)", i)
这将搜索任何长度为 16 的字符串,其中包含任何数字 (\d)、'A'、'B'、'C'、'D'、'E' 或 'F'
【讨论】:
【参考方案3】:你可以试试这个,假设十六进制代码总是以UnReg
开头
re.findall(r'UnReg\s+([\dA-F]16)',';'.join(myString))
【讨论】:
谢谢。似乎工作得很好。由于正则表达式所在的现有函数结构,我更喜欢 re.search 方法。但是,如果我不正确,我将使用这个 sn-p。【参考方案4】:使用re.findall
避免for循环。我会在模式中指定UnReg
(如果您的真实数据中有一个),这样正则表达式就不会包含其他 16 个字符的文本。
>>> import re
>>> newArr = re.findall(r'UnReg\s(.16)', ' '.join(myString))
>>> print(newArr)
['5A594F4380661123', '5A594F43805FA456', '4244434D73B24789', '5A594F43805FB000']
【讨论】:
啊,我明白你的意思了。说得通。好的,让我测试一下并回复你。 @StephanDuToit btw 有用吗? 抱歉回复晚了。是的,它在一定程度上做到了。一旦我开始使用非常大的列表,我就会发现一些小问题,比如某些类型的数字匹配不正确。但这仅仅是因为您的代码是基于我提供的信息。我应该提供更多细节。无论如何,我最终使用了@triplee 代码的略微修改版本: (? 【参考方案5】:在你的正则表达式中更具体:告诉它你知道什么!
如果您明显意识到实际结果与预期结果在某些特定方面有所不同,请尝试从中获得优势。
\w
匹配字母 ([A-Za-z]
)、数字 ([0-9]
) 和 _
,您似乎正在搜索 16 位十六进制数字。构建一个特定的character class。
另一个观察结果是您希望将 16 位十六进制数字块括在空格中,这可以通过捕获部分周围的字符正则表达式 befor(capt)after
或添加 anchors/boundaries 来表示。
【讨论】:
注意,谢谢!我收到了一些建议的解决方案。去测试每一个,然后研究它背后的方法。 @StephanDuToit 还考虑了描述上下文的非捕获部分。祝你好运:)以上是关于正则表达式从字符串中提取特定文本[重复]的主要内容,如果未能解决你的问题,请参考以下文章
构建正则表达式(RegEx)以提取 HTML 标记的文本 [重复]