Предполагая, что каждая строка представляет двоичное число в форме с прямым порядком байтов (биты нумеруются с нуля, что относится к последнему символу строки), определяя, все ли нечетные биты (т. Е. Бит № 1, бит № 3), бит № 5 и т. д.) в строке выполняется путем проверки соответствия строки этому регулярному выражению:
^[01]?(?:1[01])*$
Чтобы понять это, сначала давайте упростим, предположив, что мы уже знаем, что все символы либо0
или 1
.Учитывая это (и игнорируя хитрость без захвата), мы могли бы написать (в развернутом виде):
^ .? (1.)* $
A BB CCCCC D <- the key
Это привязанное соответствие всей строки (A
и D
), которая являетсяпустая строка или любая цифра (B
) или любое число из 1
, за которым следует что-либо (C
, которое ставит 1
в «нечетную» позицию) или цифру перед четным числом цифр с1
в «нечетном» положении (B
, за которым следует C
).Я только что преобразовал эту базовую форму в более эффективное и точное представление перед ней, ограничив алфавит символов ([01]
для .
) и используя не захватывающие скобки ((?:…)
вместо (…)
).
Если вы рассматриваете первый бит как бит № 1, вам нужен этот RE вместо:
^1?(?:[01]1)*$
Для битовых строк с младшим порядком байтов вам нужно "обратить RE"(или используйте обратная строка в строке для сопоставления и используйте один из других сопоставителей)."Обратное RE" для формы с прямым порядком байтов # 0 первой:
^(?:[01]1)*[01]?$
Для бита с прямым порядком # 1 первой:
^(?:1[01])*1?$
Помните, со всемииз этих регулярных выражений проще всего записать их в Tcl, заключив их в {
фигурные }
фигурные скобки.
Демонстрация:
foreach s {
110010001010101111110110
11010101010101111110110
11101101010101100011011
11111100110101010111101
1110111011111010111010
} {
set matches [regexp {^[01]?(?:1[01])*$} $s]
puts "$s [lindex {{doesn't match} matches} $matches]"
}
Создает этот вывод:
110010001010101111110110 doesn't match
11010101010101111110110 doesn't match
11101101010101100011011 doesn't match
11111100110101010111101 doesn't match
1110111011111010111010 matches