我想提取.txt文件中特定关键字内的所有单词。对于关键字,有一个起始关键字PROC SQL;
(我需要区分大小写),结束关键字可以是RUN;
,quit;
或QUIT;
。这是我的示例.txt
file。
到目前为止,这是我的代码:
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)
输出:
[('quit;', ''), ('quit;', ''), ('PROC SQL;', '')]
但是,我的预期输出是使单词介于两者之间,并包含关键字:
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;
任何建议或其他解决方法将不胜感激!
但是,有没有一种方法可以将这些行分隔成类似下面的样子?:
答案 0 :(得分:2)
如果不想使用正则表达式的解决方案:
=
MID(
Fields!sql.Value,
INSTR(Fields!sql.Value, "WHERE ", Compare:= Comparemethod.Text) + 6
)
对您有帮助吗?
答案 1 :(得分:1)
我认为您的模式(PROC SQL;|proc sql;(.*?)RUN;|quit;|QUIT;)
是一个错字,因为您在)
之后和proc sql;
之前以及右括号{之前都缺少右括号(.*?)
{1}}之后。但是,还不止这些,修正错字仍然无法达到预期的效果。
看看re
的Python文档:
(
(点)。在默认模式下,它匹配换行符以外的任何字符。如果指定了.
标志,则它与包括换行符的任何字符匹配。
由于您的输入中确实包含您希望DOTALL
匹配的换行符,因此您需要使用.
标志。当我们讨论标志时:如果您确实不关心关键字的区分大小写,则可能还想使用re.DOTALL
标志。
此外,我想您不想在结果中使用类似re.IGNORECASE
之类的关键字,因此您可以使用PROC SQL;
,这是常规括号的非捕获版本。
最终的正则表达式模式:
(?:...)
更新:
在上面Jupyter单元中的更新代码中,re.findall(r"(?:PROC SQL;)(.*?)(?:RUN;|QUIT;)", text, flags=re.IGNORECASE|re.DOTALL)
的结果保存为变量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
答案 2 :(得分:1)
这对我有用:
re.findall(r"(?i:PROC SQL;)((?s:.*?))(?i:RUN;|QUIT;)", text)
这是您可以接受的解决方案吗?
答案 3 :(得分:1)
您可以通过匹配关键字并匹配所有以colNumbers = []
def letterTonumber(col):
A = ord('A')
tempSum = sum(ord(l) - A + 1 for l in col if 'A' <= l <='Z')
return(tempSum)
def colParse(colNumbers, cols):
for c in cols:
if len(c) == 2:
x=26*letterTonumber(c[0])
y=letterTonumber(c[1])
n=(x+y)-1
else:
n = letterTonumber(c)-1
colNumbers.append(n)
cols = ['A','Z','AA','BB']
colParse(colNumbers, cols)
print(colNumbers)
>>> 0,25,26,53
或quit
开头的行来更有效地进行匹配,以防止由RUN
引起的不必要的回溯
如果要在匹配项中包含关键字,则可以省略捕获组。
您可以使用.*?
标志获得不区分大小写的匹配,并使用re.IGNORECASE
,因为该模式包含一个断言字符串开头的锚点。
re.MULTILINE
^PROC SQL;.*\n(?:(?!RUN;|QUIT;).*\n)*(?:RUN|QUIT);
行首^
字面上匹配PROC SQL;
匹配0+次除换行符以外的任何字符,然后匹配换行符(或使用.*\n
\r?\n
非捕获组
(?:
断言直接在右边的不是(?!RUN;|QUIT;)
或RUN;
QUIT;
匹配0+次除换行符以外的所有字符,然后匹配换行符.*\n
关闭组并重复0次以上)*
匹配(?:RUN|QUIT);
或RUN;
例如
QUIT;