- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有很多行文本,例如这一行:
row = ' S.G. Primary School\t\t 434,612.50'
我想找到一个看起来像会计师那样格式化的数字,然后我想向后看并提取该数字前面的一个或多个单词。我有这个号码:
test = re.search(r"""(?=((-?\d{1,3})(,\d{3})*(\.\d\d)?$|^\.\d\d$))""",row)
S.G. Primary School 434,612.50
test.groups()
('434,612.50', '434', ',612', '.50')
这看起来是正确的。我有完整的数字和它的部分(我想要的全部)。但是我无法弄清楚如何通过前瞻性断言在数字之前获取单词(或短语)。
我试过:
test = re.search(r"""([A-Za-z ].*) (?=((-?\d{1,3})(,\d{3})*(\.\d\d)?$|^\.\d\d$))""",row)
(' S.G. Primary School\t\t', '434,612.50', '434', ',612', '.50')
这周我花了 4 个小时重新阅读正则表达式文档,但我仍然不知道我是否有所收获。示例似乎对我不起作用。我不能使用\w+ 因为我希望标签只是文本和空格,但我也想从匹配数字的开头开始倒数。这听起来像是一般格式为“\w+(?=\d)”的“积极前瞻断言”,但这对我不起作用。
此外 - 我对分配 MULTIPLE 前瞻断言的正确方法感到困惑,这些断言在匹配返回之前都需要为真:
是
r"""([A-Za-z ]*)(.*?)([\d,.]+)(?=[A-Za-z ]*)(?=[\d,.])"""
任何不同于
r"""([A-Za-z ]*)(?=[A-Za-z ]*)(.*?)([\d,.]+)(?=[\d,.])"""
因为在这个例子中两者产生相同的结果:
(' S', '.G. Primary School\t\t ', '434,612.5')
更新
以下是我正在努力寻找正则表达式答案的三个示例:
import re
rows = [' S.G. Primary School\t\t 434,612.50',
' S.G. Bad Primary School\t\t 434,612.50',
' N.3#=42^2492q\t\t\t 434,612.50']
for row in rows:
test = re.search(r"""(?!\s)([A-Za-z]{0,25}) ?([a-zA-Z]{6,25}).*?(?=(?:(?:-?\d{1,3})(?:,\d{3})*(?:\.\d\d)?$|^\.\d\d$))((-?\d{1,3})(,\d{3})*(\.\d\d)?$|^\.\d\d$)""",row)
if test != None:
print test.groups()
else:
print test
返回:
('Primary', 'School', '434,612.50', '434', ',612', '.50')
('Bad', 'Primary', '434,612.50', '434', ',612', '.50')
None
我希望结果是:
('Primary', 'School', '434,612.50', '434', ',612', '.50')
('Primary', 'School', '434,612.50', '434', ',612', '.50')
('', '434,612.50', '434', ',612', '.50')
我希望代码可以调整,这样我也可以返回:
('School', '434,612.50', '434', ',612', '.50')
('School', '434,612.50', '434', ',612', '.50')
('', '434,612.50', '434', ',612', '.50')
有修改。
更新
根据 Casimir 的回答,这会返回更好的数据,但我不明白如何在数字前面获取多个单词短语:
test = re.search(r'([A-Za-z][A-Za-z_.]*){1,2}\s+((-?\d{1,3})(,\d{3})*(\.\d\d)?$|^\.\d\d$)',row)
('School', '434,612.50', '434', ',612', '.50')
('School', '434,612.50', '434', ',612', '.50')
('q', '434,612.50', '434', ',612', '.50')
我也不知道为什么
test = re.search(r'([A-Za-z_.]*){1,2}\s+((-?\d{1,3})(,\d{3})*(\.\d\d)?$|^\.\d\d$)',row)
给出一个错误:没有什么可重复的。我所做的只是改变
[A-Za-z][A-Za-z_.]*){1,2}
到
[A-Za-z_.]*){1,2}
在第一组。
也许:
test = re.search(r'([A-Za-z][A-Za-z_.]*){0,}\s+([A-Za-z][A-Za-z_.]*){0,}\s+((-?\d{1,3})(,\d{3})*(\.\d\d)?$|^\.\d\d$)',row)
更好,因为我得到了第一个词和第二个词,但不确定如何将它们组合起来并使它们成为可选的:
('Primary', 'School', '434,612.50', '434', ',612', '.50')
('Primary', 'School', '434,612.50', '434', ',612', '.50')
('q', None, '434,612.50', '434', ',612', '.50')
更新
我已经将 Casimir 的答案(稍作修改){0,2} 更改为 {0,1} 并使用 findall 版本对其进行了测试:
import re
rows = [' S.G. Primary School\t\t 434,612.50 S.G. Primary School\t\t 434,612.50',
' S.G. Bad Primary School\t\t 434,612.50 Bad Primary School\t\t 434,612.50',
' N.3#=42^2492q\t\t\t 434,612.50 N.3#=42^2492q\t\t\t 434,612.50 N.3#=42^2492q\t\t\t 434,612.50 ']
for row in rows:
test = re.findall(r"(?i)([a-z][a-z_.]*(?:\s+[a-z][a-z_.]*){0,1})?\s+((-?\d{1,3})(?:,\d{3})*(?:\.\d\d)?$|^\.\d\d$)",row)
test = re.findall(r"(?i)([a-z][a-z_.]*(?:\s+[a-z][a-z_.]*){0,1})?\s+(-?\d{1,3}(?:,\d{3})*(?:\.\d\d)?)",row)
print test
但是第一个测试返回这个(当第二个测试语句被注释掉时):
[('Primary School', '434,612.50', '434')]
[('Primary School', '434,612.50', '434')]
[]
第二个测试语句返回这个,一个结果列表——我想要的,排序:
[('Primary School', '434,612.50'), ('Primary School', '434,612.50')]
[('Primary School', '434,612.50'), ('Primary School', '434,612.50')]
[('q', '434,612.50'), ('q', '434,612.50'), ('q', '434,612.50')]
但是语句是如此相似,我不知道为什么会缺少列表中的多个数字/标签。
最佳答案
你根本不需要前瞻:
(?i)([a-z][a-z_.]*(?:\s+[a-z][a-z_.]*){0,2})?\s+(-?\d{1,3}(?:,\d{3})*(?:\.\d\d)?)
使用 {0,...}
,您可以控制所需的字数。如果您想要所有单词,请将其替换为 *
。如果你想要一个单词最大,你必须删除所有非捕获组:
(?i)([a-z][a-z_.]*)?\s+(-?\d{1,3}(?:,\d{3})*(?:\.\d\d)?)
如果您只需要 3 个单词:
(?i)([a-z][a-z_.]*(?:\s+[a-z][a-z_.]*){2})\s+(-?\d{1,3}(?:,\d{3})*(?:\.\d\d)?)
如果你想避免来自“非单词”的单个字母(比如“q”字母),你可以添加:
(?i)((?:^|(?<=\s))[a-z][a-z_.]*(?:\s+[a-z][a-z_.]*){0,2})?\s+(-?\d{1,3}(?:,\d{3})*(?:\.\d\d)?)
图案细节:
(?i) # make the pattern case insensitive
( # open the first capturing group
(?:^|(?<=\s)) # begining of the string or lookbehind with space
[a-z][a-z_.]* # a letter and zero or more chars from [a-z_.]
(?: # open a non-capturing group
\s+ # one or more spaces
[a-z][a-z_.]* # a letter and zero or more chars from [a-z_.]
){0,2} # repeat the capturing group zero or two times
)? # close the capturing group and make it optional
\s+ # one or more spaces
( # open a capturing group
-? # - sign optional
\d{1,3} # between 1 or 3 digits
(?:,\d{3})* # a group (zero or more times) with a , and 3 digits
(?:\.\d\d)? # an optional group with a . and 2 digits
) # close the second capturing group.
关于python - 前瞻断言和使用 python 正则表达式分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18282035/
我有一个看起来像这样的字符串: text = "9) 9 的文本\r\n10) 10 的文本\r\n11) 11 的文本\r\n12) ...\r\n123) 123 的文本" 我正在尝试将其拆分如下
下一代的 3D Tiles 前瞻 原文:Introducing 3D Tiles Next, Streaming Geospatial to the Metaverse 原文发布时间:2021年11月
我有一个使用正则表达式回顾的 string.replace() 函数。 myString.replace(/(?
我是一名优秀的程序员,十分优秀!