Поиск вертикальных регулярных выражений php

У меня есть строка, описывающая матрицу из n x m элементов, подобных этой:

§inputmap = "
~~~~~~~~~~~~~~~~~~~~B~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~BBB........BBB~~~~~~~~~~~~~
~~~~~~~~~~BB...............FBB~~~~~~~~~~
~~~~~~~~BB....................BB~~~~~~~~
~~~~~~BB.....F..................BB~~~~~~
~~~~~BB.....................F.....B~~~~~
~~~~B..............................B~~~~
~~~B........F.......................B~~~
~~BB.........F......................BB~~
~~B................F.................BB~
~BF....F....F........................FB~
~B.....................................B
B.....................................FB
B........F......F......................B
B...........................F..........B
B......................................B
B......................................B
B.......F.......................F......B
B......FFF.............................B
B.......F.............................FB
~B..................F.................FB
~BF...........................F.......B~
~~B...F...........F..........FFFFF.F.BB~
~~BB..................F..F....F.....BB~~
~~~B.......................FF.FF....B~~~
~~~~B..............................B~~~~
~~~~~BB...........................B~~~~~
~~~~~~BB........................BB~~~~~~
~~~~~~~~BB..........F..........B~~~~~~~~
~~~~~~~~~~BB................BB~~~~~~~~~~
~~~~~~~~~~~~~BBB.......F.BBB~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~BBBBBB~~~~~~~~~~~~~~~~~
";
$inputmap = trim($inputmap);

Мне нужно создать регулярное выражение (или что-то еще) для поиска строки:

$search = "
*F*
FFF
*F*
";
$search = trim($search);

на всей сетке. На других руках мне нужно найти паттерн из 5 различных букв "F" (3 по вертикали и 3 раза в горизонтальном направлении), чтобы вернуть позицию строк/столбцов паттерна, найденных на карте.

Учитывая, что входная матрица может быть различной (5x5 или 10x10 или 20x25 или...), есть ли способ решить мою проблему с php и регулярными выражениями?

Ответ 1

Вы можете сделать что-то вроде этого (без регулярных выражений):

$map = explode("\n", $inputmap);

for ($vcount = 0; $vcount < sizeof($map); ++$vcount) {  // Loop through the map vertically
    for ($hcount = 0; $hcount < strlen($map[$vcount]); ++$hcount) { // Loop through each character of each line
        if ($map[$vcount][$hcount] == "F") {
            if ($map[$vcount + 1][$hcount - 1] == "F" && $map[$vcount + 1][$hcount] == "F" && 
                $map[$vcount + 1][$hcount + 1] == "F" && $map[$vcount + 2][$hcount] == "F")
                echo "Pattern found, starting at : (v)$vcount x (h)$hcount";
        }
    }
}

$> php test.php
php test.php
Pattern found, starting at : (v)18 x (h)8
Pattern found, starting at : (v)22 x (h)30
$>

Но я должен признать, что это может занять некоторое время для сверхбольших карт.

/!\добавить код, чтобы убедиться, что строка $vcount + 1/2 действительно существует, и char $hcount + 1 тоже.

Ответ 2

Вы можете использовать $length=strstr($inputmap,"\n"), чтобы найти ширину каждой строки. Затем вы можете создать регулярное выражение, которое найдет F, за которым последуют ($length-2) другие символы, затем 3 Fs, за которыми следуют ($length-2) другие символы, а затем F.

Ответ 3

Вы можете использовать следующий код:

$lines = array_filter(preg_split("#\r\n?|\n#", $string)); // Creating array of lines
$matrix = array_map('str_split', $lines); // Creating a matrix

foreach($lines as $line_number => $line_content){ // Looping through the lines
    $pos = strpos($line_content, 'FFF');
    if(!$pos === false){// If FFF found
        while(true){
            if(isset($matrix[$line_number-1][$pos+1],$matrix[$line_number+1][$pos+1]) && $matrix[$line_number-1][$pos+1] == 'F' && $matrix[$line_number+1][$pos+1] == 'F'){ //Checking ...
                echo 'Found at: X:'.$pos.' & Y:'.$line_number.'<br>'; // Ouput
            }
            $pos = strpos($line_content, 'FFF', $pos+1); // Search further
            if(!is_int($pos)){
                break;
            }
        }
    }
}

Что происходит?

  • Мы создаем массив строк
  • Мы создаем матрицу
  • Мы перебираем строки и выполняем поиск FFF, чтобы повысить производительность. Поэтому вместо того, чтобы перебирать всю матрицу и искать F, мы непосредственно ищем FFF
  • Проверьте, существует ли значение в матрице (чтобы предотвратить ошибки индекса undefined), а затем проверьте, равно ли оно F
  • Выход
  • Искать в той же строке

онлайн-демонстрация

Обратите внимание, что координаты - это центр +

Ответ 4

попробуйте с этим шаблоном:

если конец строки \n:

$pattern = '~F.{'. ($n-2) . '}FFF.{' . ($n-2) . 'F~s';

если конец строки \r\n, затем замените на $n-3

или лучше использовать трюк quinxorin, чтобы узнать длину строки до \n

Ответ 5

@FrankieTheKneeMan и все... мой первоначальный подход состоял в том, чтобы построить регулярное выражение "n" для символов "n" входной сетки. Что-то вроде...

$search_001 = "
.F......................................
FFF.....................................
.F......................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
";


$search_002 = "
..F.....................................
.FFF....................................
..F.....................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
";

(... omissis...)

$search_100 = "
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
..........F.............................
.........FFF............................
..........F.............................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
";

(... omissis...)

$search_999 = "
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
......................................F.
.....................................FFF
......................................F.
";

где "." obvioulsy означает любой символ.

Это глупая идея?!?