найти конкретную комбинацию чисел в пределах от и до текста - PullRequest
0 голосов
/ 26 августа 2018

Я хочу только совпадение с 3-значным числом (меньше 600, например, ниже "598"), когда между начальной и конечной формулировками виден определенный номер в строке. С помощью регулярного выражения ниже я получаю совпадение всего, кто-нибудь может помочь?

Регулярное выражение: (?<=Start)(.*)(?=End).

Тестовая строка:

Начало 440 3 956 4 603 5 - 6 603 7 440 8 - 9 440 10 956 11 440 12 603 13 2005 14 440 15 598 16 1156 17 946 18 761 19 761 20 946 21 598 22 598 23 1156 24 2057 25 946 26 1194 27 946 28 946 - - - Цюрих 2019 MTWTFSS - - - - 1 - 2 1058 3 542 4 852 5 - 6 1517 7 1058 8 - 9 1058 10 848 11 542 12 705 13 1306 14 1058 15 1258 16 2159 17 1617 18 700 19 863 20 700 21 1258 22 1911 23 1911 24 1617 25 1258 26 2759 27 1258 28 1258 - - - Конец

Ответы [ 4 ]

0 голосов
/ 26 августа 2018
#!/usr/bin/perl
use Modern::Perl;
use Data::Dumper;

my $str = 'Start 440 3 956 4 603 5 - 6 603 7 440 8 - 9 440 10 956 11 440 12 603 13 2005 14 440 15 598 16 1156 17 946 18 761 19 761 20 946 21 598 22 598 23 1156 24 2057 25 946 26 1194 27 946 28 946 - - - Zurich 2019 M T W T F S S - - - - 1 - 2 1058 3 542 4 852 5 - 6 1517 7 1058 8 - 9 1058 10 848 11 542 12 705 13 1306 14 1058 15 1258 16 2159 17 1617 18 700 19 863 20 700 21 1258 22 1911 23 1911 24 1617 25 1258 26 2759 27 1258 28 1258 - - - End';

my $threshold = 600;
my $re = qr/
    (?:             # start non capture group
        Start       # literally
      |             # OR
        \G          # iterate from last match position
    )               # end group
    (?:(?!End).)*?  # make sure we don't have "End" before to number to find
    (?<!\d)         # negative lookbehind, make sure we don't have a digit before
    (\d{3})         # 3 digit number
    (?!\d)          # negative lookahead, make sure we don't have a digit after
/x;
# Retrieve all 3 digit numbers between Start and End
my @numbers = $str =~ /$re/g;
# Select numbers that are less than $threshold. In this case 600
@numbers = grep { $_  < $threshold } @numbers;

say Dumper \@numbers;

Выход:

$VAR1 = [
          440,
          440,
          440,
          440,
          440,
          598,
          598,
          598,
          542,
          542
        ];
0 голосов
/ 26 августа 2018

Если вы ищете конкретное число, например, число, близкое к 600, я бы предложил использовать regexp, чтобы собрать все числа, а затем использовать некоторый алгоритм, чтобы найти соответствующее число.

Это регулярное выражение поможет вам проверить, соответствует ли ваша строка шаблону, и собрать все числа, используя группу "число".

^Start (([^\d]+ )*((?<number>\d+) )*)*End$ 

Это более простое регулярное выражение поможет вам собирать числа без проверки всех строк:

\d+

Выполните итерацию по своей коллекции номеров и найдите нужную.

Извините, я не заметил, на каком языке вы пишете фрагмент кода.

0 голосов
/ 26 августа 2018

Попробуйте этот шаблон:

(?<=^|\D)[1-5]?\d{2}(?!.+Start)(?=\D.+End)

(?<=^|\D)[1-5]?\d{1,2} это будет соответствовать всем 1- или 2-значным числам, так как они меньше 600. Это также находит 1 **, 2 **,3 **, 4 **, 5 ** чисел.

(?!.+Start)(?=\D.+End) этот прогноз позволяет нам быть на до End слова и не до Start слово, то есть между ними.Это не может быть сделано с положительным взглядом, как заявлено @TimBiegeleisen, так как оно будет иметь переменную длину.

Демо

0 голосов
/ 26 августа 2018

С \b[0-5]\d{2}\b вы найдете все трехзначные числа до 600. Демо: https://regex101.com/r/0ZSbbY/2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...