Как проверить актуальность регулярного выражения? - PullRequest
2 голосов
/ 15 июля 2009

Допустим, у нас есть два регулярных выражения:

1234.*

и

.*

Ввод:

1234567

Очевидно, они обасоответствует, но 1234. * соответствует лучше, поскольку оно более конкретное.т.е. более актуально.Существует ли стандартный способ проверки, который более актуален?

edit:

Некоторые пояснения.Я хочу принимать решения, проверяя, какое регулярное выражение соответствует входным данным.В этом случае я только совпадающие номера.

Пример с телефонными номерами:

Ввод:

31882481337

У нас есть правило для каждого из следующих регулярных выражений:

31.*
.*

В этомСценарий Я хотел бы использовать правило, которое связано с 31. *, потому что это более конкретно для данного ввода.Если бы я не использовал регулярные выражения, это было бы легко, потому что я мог бы использовать механизм оценки, чтобы проверить, насколько он соответствует, однако в этих правилах могут быть более продвинутые регулярные выражения, такие как:

31[89].*

Ответы [ 4 ]

4 голосов
/ 15 июля 2009

Я думаю, что нет простого способа сделать это. Если вы посмотрите на более сложные примеры, вы скоро поймете, что довольно сложно точно определить «более релевантный». Все вещи, как утверждения и обратные ссылки вступают в игру.

Я могу придумать два способа приблизительной оценки «актуальности».

  1. Произвольно измените входные данные и сравните количество модификаций, вызывающих сбой каждого выражения.

  2. Проанализируйте выражения itselve. Подсчитайте и сравните количество терминальных символов против подстановочных знаков, количество утверждений и все, что вам нравится.

Особенно во втором решении вы должны знать, что многие альтернативы, которые не используются при фактическом сопоставлении, могут сделать результат несущественным.

h.*|verylongtext|anotherverylongtext

hell.*|v.*

При сопоставлении слова "привет" второе выражение является "более релевантным", но первое содержит гораздо больше терминальных символов и может получить намного лучшее ранжирование по второму решению. Но для сопоставления «очень длинного текста» первое «более актуально». Это показывает, что «релевантность» сильно зависит от фактического ввода, и вам придется анализировать фактический путь сопоставления - то, что неявно делается первым решением. Но случайное изменение входных данных является довольно сложной задачей, поскольку пространство возможных входных данных довольно велико. Я думаю, это тоже не очень хорошо сработает.

1 голос
/ 14 декабря 2010

Прошло много времени с тех пор, как я задал этот вопрос, но я хотел сообщить вам, что я придумал в конце. Я выбрал гораздо более простой подход, просто добавил весовой коэффициент к своим регулярным выражениям. Таким образом, вы можете сказать, что я сам определил актуальность регулярного выражения вместо того, чтобы пытаться определить его с помощью регулярных выражений:

Expression      Relevance
31.*              1
.*              0
1 голос
/ 15 июля 2009

один фактор, о котором я могу думать, это то, является ли язык бесконечным или не бесконечным. «Не бесконечное» определенно более актуально, чем «Бесконечное», поскольку в языке имеется конечное число приемлемых слов.

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

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

Я не уверен ни в одном стандарте, как измерить релевантность регулярных выражений.

Чтобы изложить идею правильных подмножеств, вы можете спросить, на каком языке вы говорите, и принимает ли ваше регулярное выражение слова вне этого? Ваше выражение может все еще работать, но оно содержит более широкий диапазон слов, чем вы предполагали ... конечно, это может не иметь значения, если ваш ввод контролируется, но это один из способов измерения релевантности. принимает ли он мой язык точно ?

ваш хороший пример, возможно, вы хотите принять числа, начинающиеся с 1234. 1234.* работает как шарм ... но это не тот язык, который вы указали. `1234 \ d * более конкретен и соответствует вашему языку в точности так, как вы указали ... таким образом, он более актуален.

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

0 голосов
/ 15 июля 2009

Я не знаю, является ли "актуальность" реальной проблемой. Каждый из них релевантен, и каждый из них будет соответствовать «1234567», как вы предлагаете. Как вы также говорите, однако, один («1234. *») является более конкретным. С помощью регулярных выражений специфичность велика (в таком простом случае, как этот), и иногда вы можете оттачивать его настолько, что понимаете, что он вам вообще не нужен (регулярное выражение). Правило № 1 регулярных выражений: не используйте их, если это не нужно. Например, чтобы соответствовать «1234567», я бы выбрал:

$source = '1234567';
if ( stripos( $source, '1234' ) === 0 ) {
  $foo = substr( $source, 4 );
  // $source began with '1234' and $foo holds the rest
} else {
  // it didn't begin with '1234'
}

Это пример PHP, но идея в том, что, поскольку вы так тщательно отточили свою принятую ценность, вам даже не нужен PCRE. «Релевантность» мало что скажет вам о регулярном выражении (как бы вы определили «релевантность» в этом контексте?), Однако я думаю, что специфичность - это более объективное измерение, и возможность использовать вместо этого строковые функции без регулярных выражений наверняка как черт быть очень измеримым (на самом деле, это логическое - есть ли регулярное выражение или нет?).

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

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