如何使用re模块解析文本文件中的颜色名称?
How to use re module to parse color names in text file?
我需要阅读文件 src/rgb.txt
,其中包含颜色的名称及其 RGB 格式的数字表示(该文件仅部分显示在下方)。每行包含四个字段:红色、绿色、蓝色和颜色名称,每个字段由一定数量的白色分隔space(制表符或space)。
我尝试使用 Python 的正则表达式(必须使用 re !)编写一个函数来读取文件并且应该 return 一个字符串列表,以便在 returned 列表它们有四个字段,由单个制表符 (\t
) 分隔。
returned 列表中的第一个字符串应该是:
'255\t250\t250\tsnow'
.
文本文件:
255 250 250 snow
248 248 255 ghost white
248 248 255 GhostWhite
245 245 245 white smoke
245 245 245 WhiteSmoke
220 220 220 gainsboro
255 250 240 floral white
255 250 240 FloralWhite
到目前为止,我的代码如下所示:
import re
def red_green_blue(filename='src/rgb.txt'):
with open('src/rgb.txt', "r") as f:
for line in f:
line = f.read().splitlines()
for i in range(len(line)):
new_line = re.sub("^\t+|\t+$", "", str(line[i]), flags=re.UNICODE)
d1 = " ".join(re.split("\t+", str(new_line), flags=re.UNICODE))
print(d1, type(d1))
return d1
我想知道是否有其他方法可以使用其他正则表达式来解决此任务,例如findall
、search
等
我还想知道如何显示 \t
,因为在我的例子中,我看到的是制表符,但不是 \t
,即 169 169 169 DarkGray
而不是 169\t169\t169\tDarkGray
。
这个怎么样:
[ \t]*(\d+)[ \t]*(\d+)[ \t]*(\d+)[ \t]*(.*)
由于您是逐行迭代文件,因此无需考虑换行,只需关注单行。
另外,假设第一行 ! $Xorg:
确实存在于文件中并将跳过它 - 因为我是 linux 中的新手所以我不知道那是什么或者是合法的一部分文件。
import re
def parse_re_gen(filename):
regex = re.compile(r"[ \t]*(\d+)[ \t]*(\d+)[ \t]*(\d+)[ \t]*(.*)")
with open(filename) as f: # "r" = "rt" and already default, no need to specify.
for line in f:
try:
yield regex.match(line).groups()
except AttributeError: # first line " ! $Xorg:~~~ " falls here.
pass
def wrapped_re():
for record in parse_re_gen():
# print(record)
print(repr("\t".join(record)))
wrapped_re()
生成器parse_re_gen
将return 逐行匹配元组。您的 teacher/professor 可能想要这个。在循环后调用 return
只会 return 最后一行。
('0', '139', '139', 'DarkCyan')
('139', '0', '139', 'dark magenta')
('139', '0', '139', 'DarkMagenta')
('139', '0', '0', 'dark red')
('139', '0', '0', 'DarkRed')
和 wrapped_re
将遍历生成器,将生成的元组与制表符作为分隔符连接起来,并通过使用 repr(str)
.
打印出原始制表符
'0\t139\t139\tDarkCyan'
'139\t0\t139\tdark magenta'
'139\t0\t139\tDarkMagenta'
'139\t0\t0\tdark red'
'139\t0\t0\tDarkRed'
旧的替代方式
将此视为 xy 问题时:为什么首先使用 re
?
没有 re
模块,一切都变得更简单、更快捷。
def parse_rgb_gen(filename):
with open(filename) as fp:
for line in fp:
print(repr(output := "\t".join(line.split())))
# do something with output
timeit.timeit
结果:
without re: 2.365
with re: 3.116
部分输出:
'139\t0\t139\tdark\tmagenta'
'139\t0\t139\tDarkMagenta'
'139\t0\t0\tdark\tred'
'139\t0\t0\tDarkRed'
'144\t238\t144\tlight\tgreen'
'144\t238\t144\tLightGreen'
最好将其转换为generator
并在for
循环中用于封装。
def parse_rgb_gen(filename="source.txt"):
with open(filename) as fp:
for line in fp:
yield "\t".join(line.split())
for item in parse_rgb_gen():
repr(item)
仅供参考:最后,假设以下是正确的解决方案(顺便说一句,如果没有堆栈溢出社区的帮助,我不会实现这个!):
import re
def red_green_blue(filename='src/rgb.txt'):
with open('src/rgb.txt') as f:
for line in f:
line = f.read()
regex = re.findall(r"[ \t]*(\d+)[ \t]*(\d+)[ \t]*(\d+)[ \t]*(.*)", line)
#print(regex)
string_list = list(map('\t'.join, regex))
print(string_list)
return string_list
谢谢。
我需要阅读文件 src/rgb.txt
,其中包含颜色的名称及其 RGB 格式的数字表示(该文件仅部分显示在下方)。每行包含四个字段:红色、绿色、蓝色和颜色名称,每个字段由一定数量的白色分隔space(制表符或space)。
我尝试使用 Python 的正则表达式(必须使用 re !)编写一个函数来读取文件并且应该 return 一个字符串列表,以便在 returned 列表它们有四个字段,由单个制表符 (\t
) 分隔。
returned 列表中的第一个字符串应该是:
'255\t250\t250\tsnow'
.
文本文件:
255 250 250 snow
248 248 255 ghost white
248 248 255 GhostWhite
245 245 245 white smoke
245 245 245 WhiteSmoke
220 220 220 gainsboro
255 250 240 floral white
255 250 240 FloralWhite
到目前为止,我的代码如下所示:
import re
def red_green_blue(filename='src/rgb.txt'):
with open('src/rgb.txt', "r") as f:
for line in f:
line = f.read().splitlines()
for i in range(len(line)):
new_line = re.sub("^\t+|\t+$", "", str(line[i]), flags=re.UNICODE)
d1 = " ".join(re.split("\t+", str(new_line), flags=re.UNICODE))
print(d1, type(d1))
return d1
我想知道是否有其他方法可以使用其他正则表达式来解决此任务,例如findall
、search
等
我还想知道如何显示 \t
,因为在我的例子中,我看到的是制表符,但不是 \t
,即 169 169 169 DarkGray
而不是 169\t169\t169\tDarkGray
。
这个怎么样:
[ \t]*(\d+)[ \t]*(\d+)[ \t]*(\d+)[ \t]*(.*)
由于您是逐行迭代文件,因此无需考虑换行,只需关注单行。
另外,假设第一行 ! $Xorg:
确实存在于文件中并将跳过它 - 因为我是 linux 中的新手所以我不知道那是什么或者是合法的一部分文件。
import re
def parse_re_gen(filename):
regex = re.compile(r"[ \t]*(\d+)[ \t]*(\d+)[ \t]*(\d+)[ \t]*(.*)")
with open(filename) as f: # "r" = "rt" and already default, no need to specify.
for line in f:
try:
yield regex.match(line).groups()
except AttributeError: # first line " ! $Xorg:~~~ " falls here.
pass
def wrapped_re():
for record in parse_re_gen():
# print(record)
print(repr("\t".join(record)))
wrapped_re()
生成器parse_re_gen
将return 逐行匹配元组。您的 teacher/professor 可能想要这个。在循环后调用 return
只会 return 最后一行。
('0', '139', '139', 'DarkCyan')
('139', '0', '139', 'dark magenta')
('139', '0', '139', 'DarkMagenta')
('139', '0', '0', 'dark red')
('139', '0', '0', 'DarkRed')
和 wrapped_re
将遍历生成器,将生成的元组与制表符作为分隔符连接起来,并通过使用 repr(str)
.
'0\t139\t139\tDarkCyan'
'139\t0\t139\tdark magenta'
'139\t0\t139\tDarkMagenta'
'139\t0\t0\tdark red'
'139\t0\t0\tDarkRed'
旧的替代方式
将此视为 xy 问题时:为什么首先使用 re
?
没有 re
模块,一切都变得更简单、更快捷。
def parse_rgb_gen(filename):
with open(filename) as fp:
for line in fp:
print(repr(output := "\t".join(line.split())))
# do something with output
timeit.timeit
结果:
without re: 2.365
with re: 3.116
部分输出:
'139\t0\t139\tdark\tmagenta'
'139\t0\t139\tDarkMagenta'
'139\t0\t0\tdark\tred'
'139\t0\t0\tDarkRed'
'144\t238\t144\tlight\tgreen'
'144\t238\t144\tLightGreen'
最好将其转换为generator
并在for
循环中用于封装。
def parse_rgb_gen(filename="source.txt"):
with open(filename) as fp:
for line in fp:
yield "\t".join(line.split())
for item in parse_rgb_gen():
repr(item)
仅供参考:最后,假设以下是正确的解决方案(顺便说一句,如果没有堆栈溢出社区的帮助,我不会实现这个!):
import re
def red_green_blue(filename='src/rgb.txt'):
with open('src/rgb.txt') as f:
for line in f:
line = f.read()
regex = re.findall(r"[ \t]*(\d+)[ \t]*(\d+)[ \t]*(\d+)[ \t]*(.*)", line)
#print(regex)
string_list = list(map('\t'.join, regex))
print(string_list)
return string_list
谢谢。