Perl: Есть ли ограничение на строку / регулярное выражение? - PullRequest
1 голос
/ 10 февраля 2012

У меня есть две модели

$good = "/(Yo)| (Me)/";
$bad = "/(an)|(nd)/";

my $thestring: "You and Me";

Тогда я разрешаю строку, если один или несколько хороших шаблонов подходят и ни один из плохих:

if (($thestring =~ $good) && ($thestring !~ $bad))
{...

Строка "Ты и я" не должна быть разрешена, и она работает для этого примера.

НО, добавляя очень много (~ 5000 символов) шаблонов в $ good (например, (x1) | ... | (xn)), оператор if иногда разрешает эту строку.

Я не понимаю, почему? Есть ли какие-то ограничения?

Edit:

В оригинальной версии я пытался определить имена: При использовании шаблона "хари" строка принимается, а без нее строка не принимается. Нормально, увидев «и» шаблон должен быть запрещен ...

my $text_to_search ="Bettina und Frank";                    #der zu pruefende Text ist jeweils ein Datensatz aus dem positiven datensatz
my $regexp_output_pos ="/(tr)|(ammi)|(hann)|(Per)|(ome)|(tel)|(ley)|(ro)|(Ya)|(ita)|(Zilv)|(Pat)|(Ale)|(llia)|(assi)|(Dell)|(ulee)|(Ur)|(ke)|(ansi)|(af)|(dh)|(leen)|(Nik)|(Anto)|(mun)|(Tild)|(vya)|(oko)|(mi)|(Emm)|(vel)|(nnon)|(olau)|(Yan)|(eld)|(land)|(tole)|(Len)|(ai)|(Sibe)|(na) /";#|(hari)/";
#my $regexp_output_neg ="/(und)|(01)|(at)|(20)/";

#my $regexp_output_pos ="/(ett)|(ran)/";
my $regexp_output_neg ="/(und)|(01)|(at)|(20)/";


if (($text_to_search =~ $regexp_output_pos) && ($text_to_search !~ $regexp_output_neg))
{
print "akzeptiert";

}
else
{
print "nicht akzeptiert"
}

Ответы [ 3 ]

2 голосов
/ 10 февраля 2012

Ваша проблема в том, что ваше регулярное выражение ожидает совпадения с "hari/", в то время как вы хотите сопоставить "hari""/tr" вместо "tr", "/und" вместо "und", "20/" вместо "20").

Кроме того, похоже, что вы не будете использовать снимки, поэтому отбросьте их:

my $regexp_output_pos = qr/tr|ammi|hann|Per|Siebe|hari|na /; # shortened for clarity, "na" is special because a space after is expected
my $regexp_output_neg = qr/und|01|at|20/;

Кстати, как вы, кажется, новичок в Perl,не ожидайте, что Perl будет не прав.В perl есть некоторые ошибки, но ваш собственный код, вероятно, содержит гораздо больше.Используемые здесь функции Perl - это базовые вещи, которые 20 лет тестировались тысячами других программистов.

2 голосов
/ 10 февраля 2012
/^(?!.*neg).*pos/s

будет соответствовать строкам, которые содержат "pos", но не содержат "neg", поэтому

my @pos = qw( tr ammi hann Per ome tel ley ro Ya ita Zilv
              Pat Ale llia ssi Del ulee Ur ke ansi af dh
              leen Nik Anto mun Tild vya oko mi Emm vel
              nnon olau Yan eld land tole Len ai Sibe na );
my @neg = qw( und 01 at 20 );

my $pos_pat = join '|', map quotemeta, @pos;
my $net_pat = join '|', map quotemeta, @neg;
/^(?!.*(?:$neg_pat)).*(?:$pos_pat)/s

Но вы можете использовать свои существующие шаблоны, если только удалите добавленные вами дополнительные символы "/" или используйте вместо них qr.

my $pos_pat = "tr|ammi|hann|Per|ome|tel|ley|ro|Ya|ita|Zilv|"
            . "Pat|Ale|llia|assi|Dell|ulee|Ur|ke|ansi|af|dh|"
            . "leen|Nik|Anto|mun|Tild|vya|oko|mi|Emm|vel|"
            . "nnon|olau|Yan|eld|land|tole|Len|ai|Sibe|na ";
my $neg_pat = "und|01|at|20";
/^(?!.*(?:$neg_pat)).*(?:$pos_pat)/s
1 голос
/ 10 февраля 2012
  1. Если RHS для = ~ или! ~ Является строкой, то она будет считаться шаблоном совпадения, а для создания точки, а НЕ выражением.

    Такесли вы поставите косые черты на обоих концах, Perl на самом деле будет искать эти косые черты в пространстве поиска.

    Поместить это другим способом, учитывая только эту часть кода:

    my $regexp_output_neg ="/(und)|(01)|(at)|(20)/";
    
    if (... && ($text_to_search !~ $regexp_output_neg)) ...
    

    if будет работать эквивалентно

    if (... && ($text_to_search !~
        m/
              \/(und)
            | (01)
            | (at)
            | (20)\/
        /x
    )) ...
    

    Так что, если $text_to_search окажется '/ und' или '01' или 'at' или '20 / ', то есть с лидирующей изавершающие косые черты включаются в первый и последний элементы соответственно, затем регулярное выражение будет соответствовать, !~ будет ложным, выражение if будет ложным, а if передаст управление предложению else.

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

  2. "НО, добавляя очень много (~ 5000 символов) шаблонов в $ good (например, (x1) | ... | (xn)), оператор if позволяет sometimes the string. "

    Из-за приведенного выше объяснения ваш шаблон" исключения ", вероятно, не соответствует тому, как вы думаете.Таким образом, добавляя дополнительные элементы в шаблон «включения», вы в конечном итоге добавляете что-то, соответствующее вашему пространству поиска, и ваш if начинает попадать в предложение then.

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