【发布时间】:2012-03-01 09:13:15
【问题描述】:
我是一名 Perl 程序员,正在尝试通过完成我之前完成的一些工作并将其转换为 Python 来学习 Python。这不是逐行翻译。我想学习 Python 技术 来完成这类任务。
我正在解析一个 Windows INI 文件。部分名称的格式为:
[<type> <description>]
<type> 是一个单词字段,不区分大小写。 <description> 可以是多个单词。
在一段之后,有一堆参数和值。它们的形式为:
<parameter> = <value>
参数没有空格,只能包含下划线、字母和数字(不区分大小写)。因此,第一个= 是参数和值之间的分隔符。等号周围可能有空格分隔参数和值。行首或行尾可能有多余的空格。
在 Perl 中,我使用正则表达式进行解析:
while (my $line = <CONTROL_FILE>) {
chomp($line);
next if ($line =~ /^\s*[#;']/); #Comments start with "#", ";", or "'"
next if ($line =~ /^\s*$/); #Ignore blank lines
if ($line =~ /^\s*\[\s*(\w+)\s+(.*)/) { #Section
say "This is a '$1' section called '$2'";
}
elsif ($line =~ /^\s*(\w+)\s*=\s*(.*)/) { #Parameter
say "Parameter is '$1' with a value of '$2'";
}
else { #Not Comment, Section, or Parameter
say "Invalid line";
}
}
问题是我已经被 Perl 破坏了,所以我认为最简单的方法是使用正则表达式。这是我到目前为止的代码......
for line in file_handle:
line = line.strip
# Comment lines and blank lines
if line.find("#") == 1 \
or line.find(";") == 1 \
or line.whitespace:
continue
# Found a Section Heading
if line.find("[") == 1:
print "I want to use a regular expression here"
print "to split the section up into two pieces"
elif line.find("=") != -1:
print "I want to use a regular expression here"
print "to split the parameter into key and value"
else
print "Invalid Line"
这里有几件事让我恼火:
- 有两个地方似乎需要使用正则表达式。进行这种拆分的 Python 方式是什么?
- 我确保去掉字符串两边的空白,然后重写字符串。这样,我不必多次进行剥离。但是,我正在重写我理解的字符串在 Python 中是一个非常低效的操作。处理此问题的 Python 方法是什么?
- 最后,我的算法看起来很像我的 Perl 算法,这似乎是说我让我的 Perl 思维妨碍了我。我的代码应该如何在 Python 中构建?
我一直在阅读各种在线教程,它们帮助我理解了语法,但在处理语言本身的方式上并没有太多帮助——尤其是那些倾向于用另一种语言思考的人。
我的问题:
- 我应该使用正则表达式吗?或者,有没有其他更好的方法来处理这个问题?
- 我的编码逻辑是否正确?我应该如何考虑解析这个文件?
【问题讨论】:
-
请务必查看
ConfigParser模块。 -
在 Perl 中你不是
corrupt,你是bless -
@SvenMarnach - 感谢您的建议,但我已经看到了。问题是 ConfigParser 将输出放入字典中,我无法保证字典中部分的顺序,这在这个特定的应用程序中非常重要。我在使用 Config::Ini 模块时遇到了与 Perl 相同的问题。此外,这让我有机会真正了解 Python 的来龙去脉。
-
从 Python 2.6 开始,您可以传入与
dict不同的类型,并使用提供有序字典的库之一。从 Python 2.7 开始,OrderedDict包含在标准库和ConfigParser的标准字典类型中。