LINUX.ORG.RU

Частичное совпадение строки с регулярным выражением.

 


0

2

Или как это правильно называется... Существует ли что-то подобное вообще?
Как-то так:
regexp = «\w+\(\)\d+»
string = «stroka()123»
trymatch(regexp, string) => match!

string = «stroka»
trymatch(regexp, string) => partial match.

string = «123»
trymatch(regexp, string) => no match.

Т.е. во 2м случае строка проходит \w+ и кончается, поэтому подпадает под часть регекспа...

★★★★

А если каждую «последующую» часть регэкспа сделать опциональной?

anonymous ()
Ответ на: комментарий от anonymous

А если каждую «последующую» часть регэкспа сделать опциональной?

Ну это понятно, но регекспов таких может быть много и они могут быть длинным и сложными. А во-вторых нужно как-то отличать частичное совпадение от полного.

Bad_ptr ★★★★ ()

наверное как-то так:

regexp = "((\w+)(\(\)\d+)*)"
string = "stroka()123"
trymatch(regexp, string, &match) 
if (match[1] == string) {
  // полное совпадение
} else if (match[2] == string) {
  // частичное совпадение
}

Slavaz ★★★★★ ()
Ответ на: комментарий от Bad_ptr

Bad_ptr

Ну это понятно, но регекспов таких может быть много и они могут быть длинным и сложными. А во-вторых нужно как-то отличать частичное совпадение от полного.

во первых ССЗБ, во вторых только делать опциональным части, и потом считать, сколько было совпадений. Иначе, ИМХО, никак. Хотя это похоже не то, что ты в действительности хочешь получить.

drBatty ★★ ()
Ответ на: комментарий от Bad_ptr

но регекспов таких может быть много и они могут быть длинным и сложными.

Будь мужиком... - напиши парсер уже.

anonymous ()
Ответ на: комментарий от drBatty

Покачто, только это нашёл:
http://stackoverflow.com/questions/2526756/can-java-util-regex-pattern-do-par...
В Java'вских регепспах есть метов hitEnd(), который возвращает, как я понял true, если во время сопоставления строки регекспу она благополучно проходила по регекспу, но потом был достигнут её конец. Кажется это то что нужно.

First you have to call one of the standard methods to apply the regex, like matches() or find(). If that returns false, you can use the hitEnd() method to find out if some longer string could have matched:

String[] inputs = { "AA", "BB" };
Pattern p = Pattern.compile("AAAAAB");
Matcher m = p.matcher("");
for (String s : inputs)
{
  m.reset(s);
  System.out.printf("%s -- full match: %B; partial match: %B%n",
                    s, m.matches(), m.hitEnd());
}
output:

AA -- full match: FALSE; partial match: TRUE
BB -- full match: FALSE; partial match: FALSE

Интересно для питона/перла есть что-то подобное?

Bad_ptr ★★★★ ()
Ответ на: комментарий от anonymous

Будь мужиком... - напиши парсер уже.

я уже начинаю об этом подумывать... %)

Bad_ptr ★★★★ ()
Ответ на: комментарий от Slavaz

Плюсую этот вариант. Немножко исправить и получится просто, и как раз то, что нужно

HerrWeigel ★★★★ ()
Ответ на: комментарий от Bad_ptr

Bad_ptr

Интересно для питона/перла есть что-то подобное?

наверняка. Только я не помню как. В php можно помещать найденные подстроки и их оффсеты в массив.

Естественно, если подвыражение не может быть пустым, то можно менять выражения на список найденных подвыражений через какой-то разделитель. Типа того

sed -r 's/.*(a)?(b)?.*/\1 \2/'
ну а потом посчитать, сколько было замен (т.к. подвыражение не пусто, то считать надо до первых двух разделителей подряд)

drBatty ★★ ()
Ответ на: комментарий от Bad_ptr

и да, есть ещё man 3 regexec, это регулярные выражения из glibc, доступны из C/C++. Там тоже есть доступ к найденным оффсетам.

drBatty ★★ ()

> regexp = «\w+\(\)\d+»

> string = «stroka»
> trymatch(regexp, string) => partial match.

> string = «123»
> trymatch(regexp, string) => no match.

взаимоисключающие параграфы же. «\w» — эквивалент «[a-zA-Z0-9_]», т.е. «123» вполне себе «\w+».

#!/usr/bin/perl

use v5.14;

sub trymatch($) {
    shift =~ /  ^\w+
                (?: \(  | $ )
                (?: \)  | $ )
                (?: \d+ | $ )
                $
             /x;

    return 'no match.'  if $& eq '';
    return 'match!'     if $' eq '';

    return 'partial match.';
}


say $_, ': ', trymatch $_  for 'stroka()123', 'stroka()', 'stroka(', 'stroka', 'stroka)123', '123';
stroka()123: match!
stroka(): match!
stroka(: match!
stroka: match!
stroka)123: no match.
123: match!
arsi ★★★★★ ()
Ответ на: комментарий от arsi

«\w» — эквивалент «[a-zA-Z0-9_]», т.е. «123» вполне себе «\w+»

Тфуты...извиняюсь. Ошибочка вышла. )

Bad_ptr ★★★★ ()
Ответ на: комментарий от arsi

тьфу, сам не посмотрел, что написал…

#!/usr/bin/perl

use v5.14;

sub trymatch($) {
    shift =~ /  ^\w+
                (?: \(  | $ )
                (?: \)  | $ )
                (   \d+ | $ )
                $
             /x;

    return 'no match.'  if $& eq '';
    return 'match!'     if $1 ne '';

    return 'partial match.';
}

say $_, ': ', trymatch $_  for 'stroka()123', 'stroka()', 'stroka(', 'stroka', 'stroka)123', '123';
stroka()123: match!
stroka(): partial match.
stroka(: partial match.
stroka: partial match.
stroka)123: no match.
123: partial match.
arsi ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.