gpt4 book ai didi

Python正则表达式与字符串匹配的问题

转载 作者:太空宇宙 更新时间:2023-11-03 16:43:52 24 4
gpt4 key购买 nike

提前抱歉这么长的帖子

编辑--

修改自诺曼的解决方案,如果我们找到精确的解决方案,则打印并返回,否则打印所有近似匹配。对于在下面第三个 Pastebin 链接上提供的字典文件中搜索 etnse 的特定示例,目前仍仅获得 83/85 匹配。

def doMatching(file, origPattern):
entireFile = file.read()
patterns = []
startIndices = []

begin = time.time()

# get all of the patterns associated with the given phrase
for pattern in generateFuzzyPatterns(origPattern):
patterns.append(pattern)
for m in re.finditer(pattern, entireFile):
startIndices.append((m.start(), m.end(), m.group()))
# if the first pattern(exact match) is valid, then just print the results and we're done
if len(startIndices) != 0 and startIndices[0][2] == origPattern:
print("\nThere is an exact match at: [{}:{}] for {}").format(*startIndices[0])
return

print('Used {} patterns:').format(len(patterns))
for i, p in enumerate(patterns, 1):
print('- [{}] {}').format(i, p)

# list for all non-overlapping starting indices
nonOverlapping = []
# hold the last matches ending position
lastEnd = 0
# find non-overlapping matches by comparing each matches starting index to the previous matches ending index
# if the starting index > previous items ending index they aren't overlapping
for start in sorted(startIndices):
print(start)
if start[0] >= lastEnd:
# startIndicex[start][0] gets the ending index from the current matches tuple
lastEnd = start[1]
nonOverlapping.append(start)

print()
print('Found {} matches:').format(len(startIndices))
# i is the key <starting index> assigned to the value of the indices (<ending index>, <string at those indices>
for start in sorted(startIndices):
# *startIndices[i] means to unpack the tuple associated to the key i's value to be used by format as 2 inputs
# for explanation, see: http://stackoverflow.com/questions/2921847/what-does-the-star-operator-mean-in-python
print('- [{}:{}] {}').format(*start)

print()
print('Found {} non-overlapping matches:').format(len(nonOverlapping))
for ov in nonOverlapping:
print('- [{}:{}] {}').format(*ov)

end = time.time()
print(end-begin)

def generateFuzzyPatterns(origPattern):
# Escape individual symbols.
origPattern = [re.escape(c) for c in origPattern]

# Find exact matches.
pattern = ''.join(origPattern)
yield pattern

# Find matches with changes. (replace)
for i in range(len(origPattern)):
t = origPattern[:]
# replace with a wildcard for each index
t[i] = '.'
pattern = ''.join(t)
yield pattern

# Find matches with deletions. (omitted)
for i in range(len(origPattern)):
t = origPattern[:]
# remove a char for each index
t[i] = ''
pattern = ''.join(t)
yield pattern

# Find matches with insertions.
for i in range(len(origPattern) + 1):
t = origPattern[:]
# insert a wildcard between adjacent chars for each index
t.insert(i, '.')
pattern = ''.join(t)
yield pattern

# Find two adjacent characters being swapped.
for i in range(len(origPattern) - 1):
t = origPattern[:]
if t[i] != t[i + 1]:
t[i], t[i + 1] = t[i + 1], t[i]
pattern = ''.join(t)
yield pattern

原文: http://pastebin.com/bAXeYZcD - 实际功能

http://pastebin.com/YSfD00Ju - 要使用的数据,应该是 8 个“ware”匹配项,但只得到 6 个

http://pastebin.com/S9u50ig0 - 要使用的数据,应该为“etnse”获得 85 个匹配项,但只获得 77 个

我将所有原始代码留在了函数中,因为我不确定到底是什么导致了问题。

您可以在任何内容上搜索“Board:isFull()”以获得下面所述的错误。

示例:

假设您将第二个 Pastebin 命名为“someFile.txt”,该文件夹位于与 .py 文件相同的目录中名为 files 的文件夹中。

file = open('./files/someFile.txt', 'r')
doMatching(file, "ware")

或者

file = open('./files/someFile.txt', 'r')
doMatching(file, "Board:isFull()")

或者

假设您将第三个 Pastebin 命名为“dictionary.txt”,位于与 .py 文件同一目录中名为 files 的文件夹中。

file = open('./files/dictionary.txt', 'r')
doMatching(file, "etnse")

--编辑

函数参数的工作方式如下:

file 是文件的位置。

origPattern 是一个短语。

该功能基本上应该是模糊搜索。它应该采用模式并搜索文件以查找完全匹配或有 1 个字符偏差的匹配。即:1 个缺失字符、1 个额外字符、1 个替换字符或 1 个与相邻字符交换的字符。

在很大程度上它是有效的,但我遇到了一些问题。

首先,当我尝试对 origPattern 使用类似“Board:isFull()”的内容时,我得到以下结果:

    raise error, v # invalid expression
sre_constants.error: unbalanced parenthesis

以上内容来自re库

我尝试过使用 re.escape() 但它没有改变任何东西。

其次,当我尝试像“Fun()”这样的其他东西时,它说它在某个索引处有一个匹配项,而该索引甚至不包含任何一个;它只是一行“*”

第三,当它找到匹配项时,它并不总是找到所有匹配项。例如,我有一个文件应该找到 85 个匹配项,但它只找到了 77 个匹配项,另一个文件有 8 个匹配项,但它只找到了 6 个。但是,它们只是按字母顺序排列的,所以这可能只是我如何处理的问题进行搜索或其他操作。

感谢任何帮助。

我也无法使用fuzzyfinder

最佳答案

我在代码中发现了一些问题:

  1. re.escape() 似乎不起作用,因为它的结果未分配。
    执行origPattern = re.escape(origPattern)
  2. 当模式正确转义时,请注意在操作模式时不要破坏转义。
    示例:re.escape('Fun()') 生成字符串 Fun\(\)。其中的两个 \( 子字符串绝不能分开:切勿删除、替换或交换没有转义字符的 \
    不良操作:Fun(\)(删除)、Fu\n(\)(交换)、Fun\.{0,2}\).
    良好的操作:Fun\)(删除)、Fu\(n\)(交换)、Fun.{0,2}\) .
  3. 您找到的匹配项太少,因为如果没有精确匹配项,您只会尝试查找模糊匹配项。 (参见 ifindexs.__len__() != 0: 行。)您必须始终寻找它们。
  4. 插入 '.{0,2}' 的循环产生了过多的模式,例如'ware.{0,2}' 表示 ware。除非您有意这样做,否则此模式将找到有两个插入的 wareXY
  5. 带有 .{0,2} 的模式无法按照描述的方式工作;它们允许一次更改和一次插入。
  6. 我不确定涉及 difflib.Differ 的代码。我不明白,但我怀疑不应该有 break 语句。
  7. 即使您使用set来存储索引,来自不同正则表达式的匹配仍可能重叠。
  8. 您不在正则表达式中使用单词边界 (\b),尽管对于自然语言来说这是有意义的。
  9. 不是错误,而是:为什么要显式调用魔术方法?
    (例如 indices.__len__() != 0 而不是 len(indices) != 0。)

我稍微重写了您的代码以解决我看到的任何问题:

def doMatching(file, origPattern):
entireFile = file.read()
patterns = []
startIndices = {}

for pattern in generateFuzzyPatterns(origPattern):
patterns.append(pattern)
startIndices.update((m.start(), (m.end(), m.group())) for m in re.finditer(pattern, entireFile))

print('Used {} patterns:'.format(len(patterns)))
for i, p in enumerate(patterns, 1):
print('- [{}] {}'.format(i, p))

nonOverlapping = []
lastEnd = 0
for start in sorted(startIndices):
if start >= lastEnd:
lastEnd = startIndices[start][0]
nonOverlapping.append(start)

print()
print('Found {} matches:'.format(len(startIndices)))
for i in sorted(startIndices):
print('- [{}:{}] {}'.format(i, *startIndices[i]))

print()
print('Found {} non-overlapping matches:'.format(len(nonOverlapping)))
for i in nonOverlapping:
print('- [{}:{}] {}'.format(i, *startIndices[i]))


def generateFuzzyPatterns(origPattern):
# Escape individual symbols.
origPattern = [re.escape(c) for c in origPattern]

# Find exact matches.
pattern = ''.join(origPattern)
yield pattern

# Find matches with changes.
for i in range(len(origPattern)):
t = origPattern[:]
t[i] = '.'
pattern = ''.join(t)
yield pattern

# Find matches with deletions.
for i in range(len(origPattern)):
t = origPattern[:]
t[i] = ''
pattern = ''.join(t)
yield pattern

# Find matches with insertions.
for i in range(len(origPattern) + 1):
t = origPattern[:]
t.insert(i, '.')
pattern = ''.join(t)
yield pattern

# Find two adjacent characters being swapped.
for i in range(len(origPattern) - 1):
t = origPattern[:]
if t[i] != t[i + 1]:
t[i], t[i + 1] = t[i + 1], t[i]
pattern = ''.join(t)
yield pattern

关于Python正则表达式与字符串匹配的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36526497/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com