繁体   English   中英

搜索文件中单词列表的完全匹配

[英]Search file for exact match of word list

关于此问题有很多问题,有些使用正则表达式,有些使用open,还有其他,但是我发现没有一个适合我的要求。

我正在打开一个包含字符串的xml文件,每行1个。 例如

<string name="AutoConf_5">setup is in progress…</string>

我想遍历文件中的每一行,并在每一行中搜索列表中单词的精确匹配。 当前代码似乎可以正常工作并打印出匹配项,但是并不能完全匹配,例如“通过”找到“通过”,“专业”找到“提供”,“过程”,“进行”等

def stringRun(self,file):
    str_file = ['admin','premium','pro','paid','pass','password','api']
    with open(file, 'r') as sf:
        for s in sf:
            if any(x in str(s) for x in str_file):
                self.progressBox.AppendText(s)

而不是使用匹配行中任何子字符串的函数“ in”,您应该使用regex“ re.search”,但我没有用python检查过它,因此可能出现了较小的语法错误,但这是一般的想法,请替换如果在您的代码中这样:

if any(re.search(x, str(s)) for x in str_file):

然后,您可以使用正则表达式的功能来搜索列表中带有单词边界的单词。 您需要在每个搜索字符串的开头和结尾添加“ \\ b”,或在以下条件下全部添加:

if any(re.search(r'\b' + x + r'\b', str(s)) for x in str_file):

如果要精确匹配,IMO,最好的方法是准备要匹配的字符串,然后在每一行中搜索每个字符串。

对于实例,您可以在标记的字符串和要匹配的字符串之间准备映射:

tagged = {'<string name="AutoConf_5">{0}</string>'.format(s): s
          for s in str_file}

dict是您要匹配的标记字符串和实际字符串之间的关联。

您可以这样使用它:

for line in sf:
    line = line.strip()
    if line in tagged:
        self.progressBox.AppendText(tagged[line])

注意:如果您的任何字符串包含“&”,“ <”或““>”,则需要转义这些字符,如下所示:

from xml.sax.saxutils import escape

tagged = {'<string name="AutoConf_5">{0}</string>'.format(escape(s)): s
          for s in str_file}

另一个解决方案是使用lxml解析您的XML树并查找与给定xpath表达式匹配的节点。

编辑:至少匹配一个单词(形成单词列表)

您有一个包含单词的字符串列表。 要匹配至少包含此列表单词的XML内容,可以使用正则表达式。

您可能会遇到2个困难:

  • 像文本文件一样解析的XML内容可以包含“&”,“ <”或““>”。 因此,您需要取消转义XML内容。
  • 您的单词列表中的某些单词可能包含RegEx特殊字符(例如“ [”或“(”),必须对其进行转义。

首先,您可以准备一个RegEx(和一个函数)以查找字符串中单词的所有出现。 为此,可以使用“ \\ b”来匹配空字符串,但只能在单词的开头或结尾处进行匹配:

str_file = ['admin', 'premium', 'pro', 'paid', 'pass', 'password', 'api']

re_any_word = r"\b(?:" + r"|".join(re.escape(e) for e in str_file) + r")\b"
find_any_word = re.compile(re_any_word, flags=re.DOTALL).findall

例如:

>>> find_any_word("Time has passed")
[]
>>> find_any_word("I pass my exam, I'm a pro")
['pass', 'pro']

要提取XML片段的内容,您还可以使用RegEx(即使在一般情况下不建议这样做,在这里还是值得的):

以下RegEx(和函数)与"<string>...</string>"片段匹配,然后在第一组中选择内容:

re_string = r'<string[^>]*>(.*?)</string>'
match_string = re.compile(re_string, flags=re.DOTALL).match

例如:

>>> match_string('<string name="AutoConf_5">setup is in progress…</string>').group(1)
setup is in progress…

现在,您要做的就是逐行解析文件。

对于演示,我使用了一个字符串列表:

lines = [
    '<string name="AutoConf_5">setup is in progress…</string>\n',
    '<string name="AutoConf_5">it has passed</string>\n',
    '<string name="AutoConf_5">I pass my exam, I am a pro</string>\n',
]

for line in lines:
    line = line.strip()
    mo = match_string(line)
    if mo:
        content = saxutils.unescape(mo.group(1))
        words = find_any_word(content)
        if words:
            print(line + " => " + ", ".join(words))

你得到:

<string name="AutoConf_5">I pass my exam, I am a pro</string> => pass, pro

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM