Ruby 问个用正则分组的问题

tim_lang · 2014年01月16日 · 最后由 Tim_Lang 回复于 2014年01月20日 · 2955 次阅读

比如我想已 1-9 以内的数字加。来分组,可以这样:

"xxxxx1.--------- 2.---------- 3.----------".split(/(?=\d+\..+)/)
#["xxxxx", "1.--------- ", "2.---------- ", "3.----------"]

问题来了,如果以罗马数字来分组的话怎么匹配。1=I, 2=II, 3=III

"aaaaa I.-------- II.-------- III.---------".split(/(?=(?:III)|(?:II)|(?:I)\.)/)
#["aaaaa ", "I.-------- ", "I", "I.-------- ", "I", "I", "I.---------"]

没太明白什么意思,你指的是这样?

"aaaaa I.-------- II.-------- III.---------".split(/(?= [IVX]+\.-+)/)
=> ["aaaaa", " I.--------", " II.--------", " III.---------"]

#1 楼 @wcp1231 IV,V,VI,VII 之后就不行了,另外问下 [IVX] 之前的空格的意思是?

"aaaaa I.-------- II.-------- III.---------IV.------V.-----VI.-----VII.-------".split(/(?= [IVX]+\.+)/)
#["aaaaa",
 " I.--------",
 " II.--------",
 " III.---------IV.------V.-----VI.-----VII.-------"]
"aaaaa I.-------- II.-------- III.---------IV.------V.-----VI.-----VII.-------"

有些有空格,有些没空格。。这么没规律,怎么弄。。。

那个空格的意思。。。。

(?= [IVX]+\.-+)

(?= )是环视,寻找一个位置而不是字符。 那么上面这个的意思是:找到一个位置,这个位置之后跟着 一个空格,然后多个由 IVX 组成的字符,然后一个点,然后多个减号。 可以看这个: http://rubular.com/r/Yn9PBykzVA

#3 楼 @wcp1231 其实我的需求就是把 I. II. III. IV. V. VI.等等之后的东西给取出来,结果相当于 I.任意字符 II.任意字符 III.任意字符 IV.任意字符 等等。

如果你说的 任意字符 不包括 IVX 这三个字符的话,可以:

> "aaaaa I.-------- II.----III.---------VI.--".scan(/([IVX]+\.[^IVX]+)/)
=> [["I.-------- "], ["II.----"], ["III.---------"], ["VI.--"]]

如果包含的话,就不一定能用正则处理了。得从具体需求入手才知道解决方案。 建议看看这篇博文: http://coolshell.cn/articles/10804.html

请根据罗马数字的相关结构进行设计

罗马数字相关格式见:

符号 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000

split(/(?=\d+..+)/) 可以简写为 split(/(?=\d+.)/)

以你的需求来说,下面的正则是可用的:

"aaaaa I.-------- II.-------- III.---------IV.------V.-----VI.-----VII.-------".split(/(?<![IVX])(?=[IVX]+\.)/)

[
    [0] "aaaaa ",
    [1] "I.-------- ",
    [2] "II.-------- ",
    [3] "III.---------",
    [4] "IV.------",
    [5] "V.-----",
    [6] "VI.-----",
    [7] "VII.-------"
]

不过记得 Ruby 有个设计精良的标准库专门是干这种活儿的。Rails 的路由用的就是那个库解析的,实在是想不起来了...

为啥不用

s.scan(/([IVXLCDM]+)./)[1]

#8 楼 @zw963 谢谢,很符合我需求,看了你的回答特意去查了下 regex 的 api,原来我只知道有 (?!pat). ?!<: Negative lookbehind assertion: ensures that the preceding characters do not match pat, but doesn't include those characters in the matched text

需要 登录 后方可回复, 如果你还没有账号请 注册新账号