我试图使用正则表达式匹配字符串中的模式。这个想法是这样的。
我有一个大小为n * m的数组,每个条目中包含G' s和非G' s。我必须以加号(+)的形式找到G的模式,所有四个加号的臂都具有相同的大小。例如,在下面给出的例子中:
BGBBGB
GGGGGG
BGBBGB
GGGGGG
BGBBGB
BGBBGB
BGB
GGG
BGB
是一种加号(+)形式,每只手臂的大小为1.
我尝试使用正则表达式解决模式,但是,它对我来说没有用。
match = [(m.start(0), m.end(0)) for m in re.finditer(r'([GG]*G)',l[i])]
仅匹配水平轴上相同臂长的图案,G位于中心。不确定如何在所有四个侧面上匹配具有相同臂长度的G的图案。将欣赏任何答案。
答案 0 :(得分:0)
根据我的理解,正则表达式在一维数组上使用时非常有用,而不像问题那样在2-dim数组上使用。
所以我倾向于说使用正则表达式可能不是一个好方法...我试图将G
格式的+
位置的固定模式匹配,每个手臂都是1个单位长:
B = 0
G = 1
matrix = (
(B, G, B, B, G, B),
(G, G, G, G, G, G),
(B, G, B, B, G, B),
(B, G, B, B, G, B),
(G, G, G, G, G, G),
(B, G, B, B, G, B),
)
pattern = (
(B, G, B),
(G, G, G),
(B, G, B),
)
def getMatrixSize(mat):
# Return (width, height)
return (len(mat[0]), len(mat))
def findPattern(mat, pat):
matches = []
matsize = getMatrixSize(mat)
patsize = getMatrixSize(pat)
for y in range(matsize[1] - patsize[1] + 1):
for x in range(matsize[0] - patsize[0] + 1):
submat_cols = mat[y:y+patsize[1]]
for i in range(patsize[1]):
submat_row = submat_cols[i][x:x+patsize[0]]
if submat_row != pat[i]:
i = -1
break
if i > 0:
matches.append((x, y))
return matches
# Run the thing
print(findPattern(matrix, pattern))
我的想法是在矩阵上滑动模式,并在矩阵的每个子段上比较模式的每个部分......
现在这是有点"硬编码"对于某种模式。
但是你总是可以从这里开始尝试让模式进化(不同的臂长)
注意:问题在于使用正则表达式,您无法执行\w{A}.\w{A}
之类的操作,其中A
将成为共享计数器...至少我是'从来没有听说过。
答案 1 :(得分:0)
我会选择使用类似矩阵的方法来解决这个问题,而不是使用正则表达式。
在您的示例中,我假设l
类似于列表,包括数据的每一行。
import pandas as pd
import numpy as np
def findPlusSigh(data, pattern):
# Find indexes which match the pattern
data = data == pattern
pattern_index = data.nonzero()
# List to store result
result = []
center_index = []
# Loop over each matched element
for i, j in zip(pattern_index[0], pattern_index[1]):
# Look for arm length from 1 to 100
for m in range(1, 100):
try:
# Break the loop if it's out of range of the data
if m > i or m > j:
break
# check the matched pattern in 4 directions, i.e., up, left,
# down, right
if (all(data[([i-m, i, i+m, i], [j, j-m, j, j+m])])):
pass
else:
break
except:
break
# If arm length >= 1
if m > 1:
# When the loop breaks, m is 1 more than the actual arm length
# So we need to minus 1
# Record the arm length
result.append(m-1)
# Record the center index
center_index.append((i, j))
return(result, center_index)
# Test data
l = ['BGBBGB', 'GGGGGG', 'BGBBGB', 'GGGGGG', 'BGBBGB', 'BGBBGB']
# The pattern you are matching
pattern = 'G'
# Convert the n by m data into an array where each element is a character
data = np.array([np.array(list(x)) for x in l])
result, center_index = findPlusSigh(data, pattern)
for i, j in zip(result, center_index):
print ("Data center (Row {}, Column{}) has a plus sign length of {}".format(
j[0]+1, j[1]+1, i))