R = /
\p{L}{3}\d{1,2} # match 3 letters followed by 1 or 2 digits
| # or
(?<=\A|\p{Space}) # match start of string or a space in a pos lookbehind
(?: # begin a non-capture group
\p{L}{3} # match three letters
| # or
\[\p{L}{3}\] # match three letters surrounded by brackets
) # end of non-capture group
(?=\p{Space}|\z) # match space or end of string in a pos lookahead
/x # free-spacing regex definition mode
"ABC catmat dogdog [rat] LAN45 eat HGF1 jkhgkj abc".scan R
#=> ["ABC", "[rat]", "LAN45", "eat", "HGF1", "abc"]
Это регулярное выражение записано условно (не в режиме свободного пробела):
R = /\p{L}{3}\d{1,2}|(?<=\A| )(?:\p{L}{3}\[\p{L}{3}\])(?= |\z)/
Теперь рассмотрим:
"ABCD123 [efg]456".scan R
#=> ["BCD12"]
Я считаю, что это согласуется с формулировкой задачи, но если "BCD12"
не должно быть совпадением, если перед ним стоит буква или следует цифра (здесь применяются оба), тогда регулярное выражение должно бытьизменено следующим образом.
R = /
(?<=\A|\p{Space}) # match start of string or a space in a pos lookbehind
(?: # begin a non-capture group
\p{L}{3} # match three letters
\d{,2} # match 0, 1 or 2 digits
| # or
\[\p{L}{3}\] # match three letters surrounded by brackets
) # end of non-capture group
(?=\p{Space}|\z) # match space or end of string in a pos lookahead
/x # free-spacing regex definition mode
"ABC catmat dogdog [rat] XLAN45 eat HGF123 jkhgkj abc".scan R
#=> ["ABC", "[rat]", "eat", "abc"]
Обратите внимание, что в обоих регулярных выражениях я заменил \p{Space}
пробелом.В свободном интервале пробелы удаляются до разбора регулярного выражения, поэтому они должны быть записаны \p{Space}
, [[:space:]]
, [ ]
(класс символов, содержащий пробел), \
символ пробела или, если необходимо, \s
для символа пробела (который включает пробелы, символы новой строки, символы табуляции и некоторые другие символы).