Skip to main content
 首页 » 编程设计

python之用于在文件中查找有效单词的正则表达式

2024年12月31日29虾米姐

我需要编写一个函数 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').