@burov0798
Пытаюсь изучать php\js

Как найти два слова в диапазоне нескольких символов между ними?

Добрый день. Реально ли сделать подобное?
Получаю весь текст с сайта и мне нужно найти на нем одно из слов из массива и проверить, есть ли в диапазоне (например 5) символов пятизначное число, если есть, то поиск нужно завершить поиск и вывести эту пару.
Пример:
$array = array("apple", "word", "new");
В полученном с помощью curl текста с сайта найти пару:
word, 18913

Данная пара может быть в любом виде, но точно известно, что рядом есть пятизначное число:
what, 10924
59012, test
VT 92918
word, 18913
site 85719
12345 Wisconsin

Возможно можно как-то регулярку составить? Либо есть другие методы, чтобы провернуть данное действие?
  • Вопрос задан
  • 95 просмотров
Решения вопроса 2
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
/(apple|word|new)\D{0,5}(\d{5})(?:\D|$)|(?:^|\D)(\d{5})\D{0,5}(apple|word|new)/
Ответ написан
Immortal_pony
@Immortal_pony Куратор тега PHP
Код предполагает, что в каждой строке искомое слово может встречать не более одного раза.
То есть, в строке типа "word.........17199,word" пара найдена не будет.

function findPair(string $text, array $words, int $range=5) {
    $rows = explode(PHP_EOL, $text);
    $numberLength = 5;
    $pair = null;
    $isNumberFound = false;
    
    foreach ($words as $word) {
        foreach ($rows as $row) {
            $wordPos = strpos($row, $word);
            $isWordInRow = $wordPos !== false;
            
            if (!$isWordInRow) {
                continue;
            }
            
            
            
            /* Going backwards first */
            $backwardSearchStart = $wordPos-1;
            $backwardSearchEnd = $backwardSearchStart - $range;
            
            for ($symbolPos=$backwardSearchStart; $symbolPos>$backwardSearchEnd; $symbolPos--) {
                // Stop backward search if we are in the very beginning of the row
                if ($symbolPos <= 0) {
                    break;
                }

                $symbol = substr($row, $symbolPos, 1);
                
                if (is_numeric($symbol)) {
                    $lastNumberPos = $symbolPos - $numberLength;
                    $digits = [];
                    
                    for ($digitPos=$symbolPos; $digitPos>$lastNumberPos; $digitPos--) {
                        $digit = substr($row, $digitPos, 1);
                        
                        if (is_numeric($digit)) {
                            $digits[] = $digit;
                        } else {
                            break;
                        }
                    }
                    
                    $isNumberFound = count($digits) === $numberLength;
                    
                    if ($isNumberFound) {
                        $number = implode(array_reverse($digits));
                        $pair = [$word, $number];
                        break;
                    }
                }
            }
            
            if ($isNumberFound) {
                return $pair;
            }
            
            
            
            /* Forward search */
            $forwardSearchStart = $wordPos+1+strlen($word);
            $forwardSearchEnd = $forwardSearchStart + $range;
            
            for ($symbolPos=$forwardSearchStart; $symbolPos<$forwardSearchEnd; $symbolPos++) {
                $symbol = substr($row, $symbolPos, 1);
                
                if (is_numeric($symbol)) {
                    $lastNumberPos = $symbolPos + $numberLength;
                    $digits = [];
                    
                    for ($digitPos=$symbolPos; $digitPos<$lastNumberPos; $digitPos++) {
                        $digit = substr($row, $digitPos, 1);
                        
                        if (is_numeric($digit)) {
                            $digits[] = $digit;
                        } else {
                            break;
                        }
                    }
                    
                    $isNumberFound = count($digits) === $numberLength;
                    
                    if ($isNumberFound) {
                        $number = implode($digits);
                        $pair = [$word, $number];
                        break;
                    }
                }
            }
            
            if ($isNumberFound) {
                return $pair;
            }
        }
    }
    
    return $pair;
}

$words = ["apple", "word", "new"];
$text = <<<TEXT
what, 10924
59012, test
VT 92918
word, 18913
site 85719
12345 Wisconsin
TEXT;


$pair = findPair($text, $words);
/* Result: 
array(2) {
  [0]=>
  string(4) "word"
  [1]=>
  string(5) "18913"
}
*/
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы