我想提取 .txt 文件中特定关键字内的所有单词。对于关键字,有一个起始关键字PROC SQL;(我需要不区分大小写),结束关键字可以是RUN;,quit;或QUIT;。这是我的示例.txt文件。
到目前为止,这是我的代码:
with open('lan sample text file1.txt') as file:
text = file.read()
regex = re.compile(r'(PROC SQL;|proc sql;(.*?)RUN;|quit;|QUIT;)')
k = regex.findall(text)
print(k)
Run Code Online (Sandbox Code Playgroud)
输出:
[('quit;', ''), ('quit;', ''), ('PROC SQL;', '')]
Run Code Online (Sandbox Code Playgroud)
但是,我的预期输出是获取介于关键字之间并包含关键字的单词:
proc sql; ("TRUuuuth");
hhhjhfjs as fdsjfsj:
select * from djfkjd to jfkjs
(
SELECT abc AS abc1, abc_2_ AS efg, abc_fg, fkdkfj_vv, jjsflkl_ff, fjkdsf_jfkj
FROM &xxx..xxx_xxx_xxE
where ((xxx(xx_ix as format 'xxxx-xx') gff &jfjfsj_jfjfj.) and
(xxx(xx_ix as format 'xxxx-xx') lec &jgjsd_vnv.))
);
1)
jjjjjj;
select xx("xE'", PUT(xx.xxxx.),"'") jdfjhf:jhfjj from xxxx_x_xx_L ;
quit;
PROC SQL; ("CUuuiiiiuth");
hhhjhfjs as fdsjfsj:
select * from djfkjd to jfkjs
(SELECT abc AS abc1, abc_2_ AS efg, abc_fg, fkdkfj_vv, jjsflkl_ff, fjkdsf_jfkj
FROM &xxx..xxx_xxx_xxE
where ((xxx(xx_ix as format 'xxxx-xx') gff &jfjfsj_jfjfj.) and
(xxx(xx_ix as format 'xxxx-xx') lec &jgjsd_vnv.))(( ))
);
2)(
RUN;
Run Code Online (Sandbox Code Playgroud)
任何建议或不同的方法来解决这个问题将不胜感激!
但是,有没有办法将线条分开,看起来像这样?:
我认为您的模式中(PROC SQL;|proc sql;(.*?)RUN;|quit;|QUIT;)有一个拼写错误,因为您在前后缺少右括号)以及proc sql;之后的(.*?)左括号(。然而,这还不是全部,修复了拼写错误后您仍然无法获得想要的结果。
查看 Python 文档re:
.(点)在默认模式下,它匹配除换行符之外的任何字符。如果DOTALL已指定该标志,则它将匹配包括换行符在内的任何字符。
由于您的输入确实包含您想要匹配的换行符.,因此您需要使用该re.DOTALL标志。re.IGNORECASE虽然我们讨论的是标志的主题:如果您确实不关心关键字的大小写敏感性,您可能还想使用该标志。
另外,我猜您不希望PROC SQL;结果中出现关键字,因此您可以使用(?:...)常规括号的非捕获版本。
最终的正则表达式模式:
re.findall(r"(?:PROC SQL;)(.*?)(?:RUN;|QUIT;)", text, flags=re.IGNORECASE|re.DOTALL)
Run Code Online (Sandbox Code Playgroud)
更新:
在上面 Jupyter 单元格的更新代码中,结果re.findall保存为变量regex。它是与模式匹配的字符串列表。如果您调用,print(regex)您将打印该列表(将显示其元素、字符串\n)。如果您不想\n,您可以改为打印元素(字符串本身):不过,print(*regex)两个元素之间的默认分隔符将是一个简单的空格字符,因此您可能需要设置sep为其他内容,例如多个换行符print(*regex, sep="\n"*5)或分隔行的-----喜欢print(*regex, sep="\n"+"-"*44+"\n")。但这是您必须决定哪种方式最适合您来展示您的结果。
另外,如果模式看起来不太混乱,您可能想使用“内联修饰符”而不是参数flags。它(?i:...)用于不区分大小写的匹配,而(?s:...)不是DOTALL标志:
re.findall(r"(?i:PROC SQL;)((?s:.*?))(?i:RUN;|QUIT;)", text)
Run Code Online (Sandbox Code Playgroud)