Прежде всего, давайте разберем ваше регулярное выражение на части, чтобы вам не приходилось делать всю эту пост-проверку
BYTE_RE = /(?:[012]?\d)?\d/
IP_RE = /#{BYTE_RE}(?:\.#{BYTE_RE}){3}/
DAY_RE = /0?[1-9]|[12]\d|3[01]/
MONTH_RE = /Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec/
YEAR_RE = /\d{4}/
DATE_RE = %r!#{DAY_RE}/#{MONTH_RE}/#{YEAR_RE}!
HOUR_RE = /[01]?\d|2[0-3]/
MIN_RE = /[0-5]\d/
SEC_RE = MIN_RE
TIME_RE = /#{HOUR_RE}:#{MIN_RE}:#{SEC_RE}\s-400/
DATETIME_RE = /#{DATE_RE}:#{TIME_RE}/
STRING_RE = /"(?:\\.|[^\\"])*"/
logLine_regex = /^#{IP_RE} - (?:\w*|-) \[#{DATETIME_RE}\] #{STRING_RE} \d{4} (?:\d+|-)$/
isVal = lg.readlines.all? { |line| line =~ logLine_regex }
BYTE_RE
принимает только строки с целочисленным значением 0-255, поэтому мы не должны проверять это впоследствии.
Это включает 000
, поэтому, если вы хотите ограничить его числами без начальных нулей, измените его на /\d|[1-9]\d|[12]\d\d/
.
DAY_RE
принимает только строки с целочисленным значением 1-31. Опять же, если вы хотите удалить ведущие нули, используйте /[1-9]|[12]\d|3[01]/
.
Нет необходимости проверять год в вашем примере - так как это ровно четыре цифры, он должен быть между 0 и 9999
включительно. Мы можем сделать то же самое для позиции 14, чтобы избежать проверки.
HOUR_RE
принимает только строки с целочисленным значением 0-23. Непринятие ведущих нулей даст /1?\d|2[0-3]/
. MIN_RE
и SEC_RE
ограничьте количество принятых строк целочисленными значениями от 0 до 59.
Затем для проверки строки мы используем STRING_RE
. Я сломаю это.
"
- открытая котировка
(?:...)
- не захватывающие парены, хорошие для группировки.
\\.
- любая комбинация обратной косой черты и буквы - соответствует экранированию строки, например \n
, \a
, \\
или \"
|
- либо предыдущий шаблон, либо следующий
[^\\"]
- любой символ, кроме обратной косой черты или двойной кавычки
*
- ноль или более предшествующего атома
"
- закрывающая цитата
Таким образом, это соответствует открытой двойной кавычке, любому количеству экранированных или обычных символов, а затем закрывающей кавычке.
Нет необходимости проверять, чтобы сумма, проверяемая регулярным выражением, была всей строкой, начиная с начала ^
и заканчивая $
якоря позаботятся об этом.
Итак, мы удалили всю вашу проверку после факта. Так как мы хотим знать, совпадают ли все строки
данное регулярное выражение, мы можем использовать Enumerable#all?
, который будет возвращать true тогда и только тогда, когда все строки совпадают
данное регулярное выражение. Кроме того, в качестве дополнительного преимущества, он выйдет досрочно, если любой из них вернет false, что означает, что это будет работать
немного быстрее в этом случае.