многострочное регулярное выражение не работает в ruby - PullRequest
0 голосов
/ 18 апреля 2019

Я написал регулярное выражение в ruby, которое отлично работает в одной строке, но оно довольно большое, поэтому мне нужно написать его в многострочном формате.

Я использую формат %r{}x, чтобы использовать егов несколько строк, но это не работает.

regex = (/\A(RM|R1)([A-Z])([A-Z])(\d+)(\d\d+)([A-Z])([A-Z])([A-Z]+)-?(\d+)([A-Z])(\d)#?([A-Z])([A-Z])(\d)\z/)

в одну строку

regex = %r{
        ([A-Z])
        ([A-Z])
        ([A-Z])
        (\d+)
        (\d\d+)
        ([A-Z])
        ([A-Z])
        ([A-Z]+)
        -?
        (\d+)
        ([A-Z])
        (\d)
        #?
        ([A-Z])
        ([A-Z])
        (\d)
     }x

в несколько строк (одна группа в каждой строке)

Что происходит не такс моим подходом?

Ответы [ 2 ]

1 голос
/ 18 апреля 2019

Вы должны экранировать символ #, как в режиме свободный интервал , он обозначает начало комментария:

Буквальный пробел внутри шаблона игнорируется, и символ octothorpe (#) вводит комментарий до конца строки .Это позволяет организовывать компоненты шаблона потенциально более читабельным образом.

Итак, замените #? на \#?.

0 голосов
/ 18 апреля 2019

Вот ваше регулярное выражение, определенное в свободном интервале , что, я думаю, вы ищете.

regex = /
        \A        # beginning of string
        (RM|R1)   # match 'RM' or 'R1'           CG  1 
        ([A-Z])   # match 1 uppercase letter     CG  2
        ([A-Z])   # match 1 uppercase letter     CG  3
        (\d+)     # match > 0 digits             CG  4
        (\d{2,})  # match > 0 digits             CG  5
        ([A-Z])   # match 1 uppercase letter     CG  6
        ([A-Z])   # match 1 uppercase letter     CG  7
        ([A-Z]+)  # match > 0 uppercase letters  CG  8
        -?        # optionally match '-'
        (\d+)     # match > 0 digits             CG  9
        ([A-Z])   # match 1 uppercase letter     CG 10
        (\d)      # match > 0 digits             CG 11
        \#?       # optionally match '#'
        ([A-Z])   # match 1 uppercase letter     CG 12
        ([A-Z])   # match 1 uppercase letter     CG 13
        (\d)      # match > 0 digits             CG 14
        \z        # end of string
        /x        # free-spacing regex definition mode

"CG" для "группы захвата".Одним из основных применений режима свободного пробела является документирование регулярного выражения, как я здесь сделал.

Я внес два изменения в ваше регулярное выражение.Во-первых, я заменил (\d\d+) на (\d{2,}), который имеет тот же эффект, но, возможно, читается лучше.Во-вторых, символ "#" начинает комментарий в режиме свободного пробела, поэтому его необходимо экранировать (\#), если он должен быть сопоставлен.

В качестве примера использования этого регулярного выражения,

test_str = "RMAB12345CDEF-6G7#HI8"
m = test_str.match regex
  #=> #<MatchData "RMAB12345CDEF-6G7#HI8" 1:"RM" 2:"A" 3:"B" 4:"123" 5:"45"
  #     6:"C" 7:"D" 8:"EF" 9:"6" 10:"G" 11:"7" 12:"H" 13:"I" 14:"8"> 
m.captures
  #=> ["RM", "A", "B", "123", "45", "C", "D", "EF", "6", "G", "7", "H", "I", "8"] 

Обратите внимание, что не ясно, как 5 цифр должны быть разделены между группами захвата 4 и 5.

Есть одна вещь, с которой вы должны быть осторожны при использовании режима свободного пробела.Все пробелы удаляются до разбора выражения, включая любые пробелы, которые вы хотите сопоставить.Например,

"ab c".match? /ab c/   #=> true
"ab c".match? /ab c/x  #=> false
"abc".match?  /ab c/x  #=> true

Вот несколько способов защитить символ пробела (все возвращают true):

"ab c".match? /ab[ ]c/x          # put in a character class
"ab c".match? /ab[[:space:]]c/x  # Unicode bracket expression 
"ab c".match? /ab\p{Space}c/x    # Unicode \p{} construct
"ab c".match? /ab\sc/x           # match a whitespace character

Обратите внимание, что \s соответствует символам табуляции, перевода строки и двум другимсимволы, а также пробелы, которые могут быть или не быть желательными.

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