Regex для n символов или не менее m символов
Это должен быть довольно простой вопрос с регулярным выражением, но я не мог найти ответы нигде. Как сделать регулярное выражение, которое соответствует только ТОЛЬКО 2 символам или не менее 4 символов. Вот мой текущий метод его выполнения (игнорируйте само регулярное выражение, что помимо точки):
[A-Za-z0_9_]{2}|[A-Za-z0_9_]{4,}
Однако этот метод занимает в два раза больше времени (и примерно на 0,3 секунды для меня в файле с 400 строк), поэтому мне было интересно, есть ли лучший способ сделать это?
Ответы
Ответ 1
Оптимизируйте начало и привяжите его.
^[A-Za-z0-9_]{2}(?:|[A-Za-z0-9_]{2,})$
(Кроме того, вы сказали, что игнорируете само регулярное выражение, но я догадался, что вы, вероятно, хотели 0-9
, а не 0_9
)
EDIT Хм, я был уверен, что прочитал, что вы хотите совместить строки. Удалите анкеры (^$
), если вы хотите также совместить внутри линии. Если вы выполняете только полные строки, привязки ускоряют вас (ну, как минимум, передний якорь ^
).
Ответ 2
Ваше решение выглядит неплохо. В качестве альтернативы вы можете попробовать что-то подобное:
[A-Za-z0-9_]{2}(?:[A-Za-z0-9_]{2,})?
Кстати, я думаю, что вы хотите дефис вместо подчеркивания между 0
и 9
, не так ли?
Ответ 3
Правильное решение.
Если вы пытаетесь оптимизировать подпрограмму, а количество совпадений строк, совпадающих с двумя или более символами, намного меньше, чем те, которые этого не делают, подумайте о принятии всех строк длиной 2 или выше, а затем бросите их, если они длины 3. Это может повысить производительность, только проверив регулярное выражение один раз, а второй вызов даже не должен быть регулярным выражением; проверка длины строки обычно является чрезвычайно быстрой операцией.
Как всегда, вам действительно нужно запускать тесты с данными в реальном мире, чтобы убедиться, что это даст вам увеличение скорости.
Ответ 4
поэтому в основном вы хотите совместить слова длины либо 2 или 2 + 2 + N, N >= 0
([A-Za-z0-9][A-Za-z0-9](?:[A-Za-z0-9][A0Za-z0-9])*)
рабочий пример:
#!/usr/bin/perl
while (<STDIN>)
{
chomp;
my @matches = ($_=~/([A-Za-z0-9][A-Za-z0-9](?:[A-Za-z0-9][A0Za-z0-9])*)/g);
for my $m (@matches) {
print "match: $m\n";
}
}
входной файл:
cat in.txt
ab abc bcad a as asdfa
aboioioi i i abc bcad a as asdfa
выход:
perl t.pl <in.txt
match: ab
match: ab
match: bcad
match: as
match: asdf
match: aboioioi
match: ab
match: bcad
match: as
match: asdf