Как я могу проверить, что каждая подстрока из четырех нулей сопровождается хотя бы четырьмя, используя регулярные выражения? - PullRequest
2 голосов
/ 20 июня 2010

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

00101011000011111111001111010 -> correct
0000110                       -> incorect
11110                         -> correct

спасибо за любую помощь

Ответы [ 3 ]

3 голосов
/ 20 июня 2010

Если вы используете Perl, вы можете использовать утверждение нулевой ширины с нулевой шириной :

#!/usr/bin/perl

use strict; use warnings;

my @strings = qw(
    00101011000011111111001111010
    00001111000011
    0000110
    11110
);

my $re = qr/0000(?!1111)/;

for my $s ( @strings ) {
    my $result = $s =~ $re ? 'incorrect' : 'correct';
    print "$s -> $result\n";
}

Шаблон соответствует, если есть строка 0000 , а не , за которой следуют как минимум четыре 1 с. Таким образом, совпадение указывает на неверную строку.

Выход:

C:\Temp> s
00101011000011111111001111010 -> correct
00001111000011 -> incorrect
0000110 -> incorrect
11110 -> correct
1 голос
/ 20 июня 2010

В то время как предполагаемые «регулярные выражения» некоторых языков на самом деле реализуют нечто совершенно иное (как правило, расширенный набор), которые в компьютерных науках называются регулярными выражениями (включая, например, автоматы нажатия или даже выполнение произвольного кода в «регулярных выражениях»), чтобы ответитьФактические термины регулярных выражений, я думаю, лучше всего сделать следующим образом:

регулярные выражения, как правило, являются хорошим способом ответить на многие вопросы вида «есть ли место в тексте, в котором встречается следующий шаблон» (конечно, с ограничениями на шаблон - например, балансировка вложенных скобок выходит за рамки регулярных выражений, хотя, конечно, это может не выходить за рамки произвольных надмножеств регулярных выражений).«Соответствует ли весь текст этому шаблону», очевидно, является частным случаем вопроса «Соответствует ли любое место в тексте этому шаблону», учитывая возможность иметь специальные маркеры, означающие «начало текста» и «конец текста» (обычно^ и $ в типичном синтаксисе регулярных выражений).

Однако вопрос «можете ли вы проверить, что ни одна точка в тексте не соответствует этому шаблону» не является ответом, который сопоставление регулярному выражению может непосредственно ответить ... но, добавив (вне регулярного выражения) логическую операцию not, очевидно, решает проблему на практике, потому что "проверить, что совпадений не найдено" явно то же самое, "скажите мне, если какие-либо совпадения точек" следуют«превратить успех в неудачу и наоборот» (последняя часть - logical not).Это ключевой момент в ответе Синан , выходящий за рамки специфического использования негативного взгляда Perl (который на самом деле просто ярлык, а не расширение мощности регулярного выражения как таковое).

Если вашлюбимый язык для использования регулярных выражений в не имеет отрицательного предвзятого отношения, но имеет {<number>} «ярлык счетчика», круглые скобки и вертикальную черту «или»:

00001{0,3}([^1]|$)

, то есть «следуют четыре 0»от нуля до трех 1 с последующим либо не-1 символом, либо концом текста "это точно такой шаблон, что, если текст соответствует ему где-либо, нарушает ваше ограничение (IOW, его можно увидетькак небольшое расширение синтаксиса ярлыков с негативным прогнозом).Добавьте логическое-нет (опять же, на любом языке, который вы предпочитаете), и вот вы!

0 голосов
/ 20 июня 2010

Есть несколько подходов, которые вы можете использовать здесь, и я перечислю некоторые из них.

Проверка того, что для всех случаев требование всегда выполняется

В этом подходе мы простонайдите 0000(1111)? и найдите все совпадения.Так как ? является жадным, он будет соответствовать 1111, если это возможно, поэтому мы просто проверяем, что каждое совпадение 00001111.Если это только 0000, то мы говорим, что ввод недействителен.Если мы не нашли ни одного совпадения, равного 0000 (возможно, из-за того, что вообще нет совпадения), мы говорим, что оно действительно.

В псевдокоде:

FUNCTION isValid(s:String) : boolean
   FOR EVERY match /0000(1111)?/ FOUND ON s
      IF match IS NOT "00001111" THEN
         RETURN false

   RETURN true

Проверка того, что есть случай, когда требование не выполнено (затем возражаем)

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

В псевдокоде

isValid := NOT (/violationPattern/ FOUND ON s)

Опция Lookahead

Если ваш аромат поддерживает это, отрицательный прогноз является наиболее естественным способом выражения этого паттерна.Просто поищите 0000(?!1111).

Опция без предварительного просмотра

Если ваш аромат не поддерживает отрицательный прогноз, вы все равно можете использовать этот подход.Теперь шаблон становится 00001{0,3}(0|$).То есть мы пытаемся сопоставить 0000, затем 1{0,3} (то есть между 0-3 1), затем либо 0, либо конец привязки строки $.

Полностью прописанный параметр

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

00000|000010|0000110|00001110|
0000$|00001$|000011$|0000111$

Проверка того, что не существует случая, когда требование не выполнено

Это основано на отрицательном прогнозе;это просто перевод предыдущего подхода на следующий уровень.Вместо:

isValid := NOT (/violationPattern/ FOUND ON s)

мы можем ввести NOT в регулярное выражение, используя отрицательный взгляд следующим образом:

isValid := (/^(?!.*violationPattern)/ FOUND ON s)

То есть, привязывая себя в начале строки, мыотрицательно утверждают, что мы можем соответствовать .*violationPattern..* позволяет нам "искать" violationPattern настолько далеко вперед, насколько это необходимо.


Вложения

Вот образцы, показанные на рубулярной:

Используемые входные данные (аннотированы, чтобы показать, какие из нихдействительны):

+ 00101011000011111111001111010
- 000011110000
- 0000110
+ 11110
- 00000
- 00001
- 000011
- 0000111
+ 00001111

Ссылки

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