Эффективный способ найти индекс токена (слова) после поиска строки регулярного выражения - PullRequest
3 голосов
/ 19 мая 2011

Мне нужно выполнить поиск по регулярному выражению для строки x в другой строке y, но затем мне нужно знать индекс токена (слова) первого символа попадания после токенизации (разбиения) строки y с использованием некоторого другого регулярного выражения. выражение (например, пробел). Первое регулярное выражение может найти подстроку, поэтому я не могу гарантировать, что оно остановится в начале токена (слова).

Какой будет лучший алгоритм для реализации этого. Простой подход будет следующим:

  1. Найдите x в y, используя первое регулярное выражение, и получите смещение символа z
  2. Разбить y на массив элементов, используя второе регулярное выражение
  3. Прокручивать массив элементов, добавляя длину каждого элемента к переменной LENGTH и добавляя 1 к счетчику COUNTER
  4. Остановите цикл, когда ДЛИНА больше или равна z
  5. Индексом токена первого символа попадания будет значение COUNTER

(Предполагается, что функция разделения хранит символы разделения (например, пробелы) в качестве элементов массива, что очень расточительно.

Конкретный (простой) пример. Предположим, я хочу узнать индекс токена (слова) для поиска «ade» в строке «Луна сделана из сыра». Функция должна дать мне ответ: 3 (для нулевых индексированных массивов).

== Edit ==
Алгоритм также должен работать, когда поиск регулярных выражений пересекает границы токенов. Например, он должен снова возвращать индекс «3» при поиске «de of ch» в «Луна сделана из сыра».

Ответы [ 2 ]

1 голос
/ 19 мая 2011

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

Вот Perl-скрипт, выполняющий эту работу:

    #!/bin/perl -w

    my $string = 'The moon is made of cheese';
    my $lookedfor = 'de of che';
    my $separator = q/\W+/;

    my $count = undef;
    if ($string =~ /(.*?)$lookedfor/) {
        # Keep the smallest (.*?) part of string before the match.
        my $firstpart = $1;

        $count = 0;
        # Count the number of separator 
        $count++ while $firstpart =~ m/$separator/g;
    }

    if (defined $count) {
        printf "index of '%s' in '%s' is %d\n", $lookedfor, $string, $count;
    } else {
        printf "No occurence of '%s' in '%s'\n", $lookedfor, $string;
    }
1 голос
/ 19 мая 2011

По вашим обновлениям:

#!/usr/bin/perl -l
use strict;
use warnings;

my $string = "The moon is made of cheese";
my $search = 'de of ch';
my $pos = index($string, $search);
if ($pos != -1) {
    my $substr = substr($string, 0, $pos);
    my @words = split /\s+/, $substr;
    print "found in word #", $#words, "\n";
} else {
    print "not found\n";
}

выход:

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