2017-05-19 3 views
1

正規表現を使用して文字列のパターンと一致させようとしました。アイデアはこれです。プラス記号を文字のグリッドに一致させる

私は、各エントリにGと非Gのサイズn * mの配列を持っています。私は正方形(+)の形でGのパターンを見つけなければなりません。プラスの4つのアームはすべて同じサイズです。例えば、実施例において以下に与えられる:私は正規表現を使用してパターンを解決しようとした1

BGBBGB 
GGGGGG 
BGBBGB 
GGGGGG 
BGBBGB 
BGBBGB 

BGB 
GGG 
BGB 

しかし、サイズの各アームを有するプラス記号(+)の形態であり、それはなかったです私のために働く。

match = [(m.start(0), m.end(0)) for m in re.finditer(r'([GG]*G)',l[i])] 

は、水平軸の同じ腕の長さのパターンと一致し、中央のGが一致します。すべての4つの側面で同じ腕の長さとGのパターンを一致させる方法がわからない。どんな答えにも感謝します。

答えて

0

正規表現は、問題のように2次元配列ではなく、1次元配列で使用すると便利です。

だから私は正規表現を使用することは良い方法ではないかもしれないと言う傾向があるだろう...私は、+パターンで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)) 

私の考えは、今これはちょっと「ハードコード化された」のためのものである...

をマトリックス上にパターンをスライドさせ、そしてマトリックスパターンの各セグメントの各サブセグメントに比較することでした特定のパターン。
しかし、あなたはいつもここから行くと(異なるアーム長)

パターンが進化できるように試みることができる:Aが共有だろうどこ正規表現で、あなたは\w{A}.\w{A}ような何かをすることができないということで問題カウンター...少なくとも私はそれについて聞いたことがない。

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))