我需要编写一个函数 get_specified_words(filename) 来从文本文件中获取小写单词列表。必须满足以下所有条件:
- 包括所有小写字符序列,包括那些 包含
-或'字符以及以'结尾的字符 性格。 - 排除以
-结尾的单词。 - 函数必须只处理开始和结束标记线之间的线
使用此正则表达式从文件的每个相关行中提取单词:
valid_line_words = re.findall("[a-z]+[-'][a-z]+|[a-z]+[ ']?|[a-z]+", 行)在使用正则表达式之前确保行字符串是小写。
打开文件进行阅读时使用可选的编码参数。那就是您的打开文件调用应该类似于 open(filename, encoding='utf-8')。如果您的操作系统未将 Python 的默认编码设置为 UTF-8,这将特别有用。
示例文本文件 testing.txt 包含以下内容:
That are after the start and should be dumped.
So should that
and that
and yes, that
*** START OF SYNTHETIC TEST CASE ***
Toby's code was rather "interesting", it had the following issues: short,
meaningless identifiers such as n1 and n; deep, complicated nesting;
a doc-string drought; very long, rambling and unfocused functions; not
enough spacing between functions; inconsistent spacing before and
after operators, just like this here. Boy was he going to get a low
style mark.... Let's hope he asks his friend Bob to help him bring his code
up to an acceptable level.
*** END OF SYNTHETIC TEST CASE ***
This is after the end and should be ignored too.
Have a nice day.
这是我的代码:
import re
def stripped_lines(lines):
for line in lines:
stripped_line = line.rstrip('\n')
yield stripped_line
def lines_from_file(fname):
with open(fname, 'rt') as flines:
for line in stripped_lines(flines):
yield line
def is_marker_line(line, start='***', end='***'):
min_len = len(start) + len(end)
if len(line) < min_len:
return False
return line.startswith(start) and line.endswith(end)
def advance_past_next_marker(lines):
for line in lines:
if is_marker_line(line):
break
def lines_before_next_marker(lines):
valid_lines = []
for line in lines:
if is_marker_line(line):
break
valid_lines.append(re.findall("[a-z]+[-'][a-z]+|[a-z]+[']?|[a-z]+", line))
for content_line in valid_lines:
yield content_line
def lines_between_markers(lines):
it = iter(lines)
advance_past_next_marker(it)
for line in lines_before_next_marker(it):
yield line
def words(lines):
text = '\n'.join(lines).lower().split()
return text
def get_valid_words(fname):
return words(lines_between_markers(lines_from_file(fname)))
# This must be executed
filename = "valid.txt"
all_words = get_valid_words(filename)
print(filename, "loaded ok.")
print("{} valid words found.".format(len(all_words)))
print("word list:")
print("\n".join(all_words))
这是我的输出:
File "C:/Users/jj.py", line 45, in <module>
text = '\n'.join(lines).lower().split()
builtins.TypeError: sequence item 0: expected str instance, list found
这是预期的输出:
valid.txt loaded ok.
73 valid words found.
word list:
toby's
code
was
rather
interesting
it
had
the
following
issues
short
meaningless
identifiers
such
as
n
and
n
deep
complicated
nesting
a
doc-string
drought
very
long
rambling
and
unfocused
functions
not
enough
spacing
between
functions
inconsistent
spacing
before
and
after
operators
just
like
this
here
boy
was
he
going
to
get
a
low
style
mark
let's
hope
he
asks
his
friend
bob
to
help
him
bring
his
code
up
to
an
acceptable
level
我需要帮助让我的代码工作。感谢您的帮助。
请您参考如下方法:
lines_between_markers(lines_from_file(fname))
为您提供有效单词列表。
所以你只需要展平它:
def words(lines):
words_list = [w for line in lines for w in line]
return words_list
成功了。
但我认为您应该检查程序的设计:
lines_between_markers 应该只产生标记之间的线,但它做的更多。正则表达式应该用在这个函数的结果上,而不是在函数内部。
你没有做的:
Ensure that the line string is lower case before using the regular expression.
Use the optional encoding parameter when opening files for reading. That is your open file call should look like open(filename, encoding='utf-8').
