多行正则表达式在Ruby中不起作用

时间:2019-04-18 09:57:34

标签: regex ruby

我用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 个答案:

答案 0 :(得分:1)

您应该像free-spacing mode一样转义#符号,它表示注释开始:

  

模式内的文字空白将被忽略,并且八字形(#)字符会在行尾添加注释,直到。这样可以以一种可能更具可读性的方式来组织模式的各个组成部分。

因此,将#?替换为\#?

答案 1 :(得分:0)

这是您在 free-spacing模式中定义的正则表达式,这正是我认为的要求。

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"] 

请注意,尚不清楚如何在捕获组4和5之间划分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会匹配制表符,换行符和其他两个字符以及空格,这可能会或可能不会。