Я пытаюсь извлечь число из определенной скороговорки.

Вот пример строки «стабильные пациенты, в том числе 3787 с».

Это число может быть где угодно после слова "пациенты" или перед словом "пациенты". Я хочу извлечь только первый набор чисел до или после определенного слова.

Пытаюсь использовать это, но не работает

function get_numerics ($str) {
    preg_match('/Patients\s*(\d+)/', $str, $matches);
    return $matches[0];
}
0
SamIAm 17 Дек 2016 в 02:07
\s* - это пробел, который вы хотите просто выделить после первого числа после пациентов, независимо от того, что находится между ними? Кроме того, Patients - это строчные буквы в вашем примере строки, вам понадобится модификатор i для регулярного выражения, чтобы это разрешить. $matches[0] будет совпадением, $matches[1] будет целым числом.
 – 
chris85
17 Дек 2016 в 02:10
Считали ли вы, что вам, возможно, придется объяснить или определить связь между числом и словом пациенты? Что, если бы в тексте были год, пациенты и количество пациентов?
 – 
user2506641
17 Дек 2016 в 02:11
Может ли номер быть где-нибудь в строке или он должен быть прямо рядом со словом «пациенты»?
 – 
4castle
17 Дек 2016 в 02:12
В Интернете есть инструменты для тестирования регулярных выражений в реальном времени. Проверьте это: regexr.com/3et6l
 – 
MikeVelazco
17 Дек 2016 в 02:13

1 ответ

Лучший ответ

Вы можете использовать два регулярных выражения: одно для поиска числа перед ключевым словом, другое для поиска числа после ключевого слова. Если какой-либо из них найден, вычислите расстояние в количестве символов между вашим ключевым словом и числом. Затем верните число, наиболее близкое к вашему ключевому слову, исходя из рассчитанных расстояний. Вы также, вероятно, захотите ограничить максимально возможное расстояние между вашим ключевым словом и числами; не имеет смысла возвращать число, состоящее из нескольких сотен символов от вашего ключевого слова, верно? Я использовал не более 20 символов ниже.

function get_numerics($str) {
    $word = 'patients';
    preg_match('/(\d+)[^\d]{1,20}?'.$word.'/i', $str, $matches_before);
    preg_match('/'.$word.'[^\d]{1,20}?(\d+)/i', $str, $matches_after);
    $distance_before = PHP_INT_MAX;
    $distance_after = PHP_INT_MAX;
    if (count($matches_before) == 2) {
        $distance_before = strlen($matches_before[0]) - strlen($matches_before[1]) - strlen($word);
    }
    if (count($matches_after) == 2) {
        $distance_after = strlen($matches_after[0]) - strlen($matches_after[1]) - strlen($word);
    }
    if (count($matches_before) == 2 || count($matches_after) == 2) {
        if ($distance_before < $distance_after) {
            return (int) $matches_before[1];
        } else {
            return (int) $matches_after[1];
        }
    }
    return FALSE;
}

var_dump(get_numerics("24 stable patients, including some"));
// Returns 24
var_dump(get_numerics("stable patients, including 3787 with"));
// Returns 3787
var_dump(get_numerics("24 stable patients, including 3787 with"));
// Returns 24, because it's the closest from the 'patients' keyword
var_dump(get_numerics("24 stable blablabla patients, including 3787 with"));
// Returns 3787, because it's the closest from the 'patients' keyword
var_dump(get_numerics("stable blablabla patients, including some that are not ok. But 3787 planes "));
// Returns FALSE, because 3787 is too far from the 'patients' keyword
0
Guillaume Boudreau 17 Дек 2016 в 02:48
Спасибо, но если у меня есть что-то вроде этого «Среди 2933 пациентов, 1948», система считывает 1948 как пациентов.
 – 
SamIAm
17 Дек 2016 в 04:27