Ruby 要匹配这样的字符串正则该如何写呢?

pepsin · 2012年04月10日 · 最后由 freemem 回复于 2012年05月30日 · 5382 次阅读

比如"Buy a cup for $30"

要匹配里面的“30”,但前置条件是“30”前必须有"$", 正则表达式是这样:/(?<=\$)[0-9.]+/,这个已知。

但字符串偶尔可能会是“Buy a cup for $ 30”,即“$”和“30”间可能偶尔有空格,正样的情况正则该如何写才能依旧匹配上“30”并符合前述条件呢?

\s*好使吗?\s表示空格,*代表或有或无

貌似直接把*?+写在零宽正向后行断言 (坑爹的名字) 不能用 这个应该能满足要求,正则很弱,也许有更好的写法 "Buy a cup for $ 30".match(/(?<=\$)\s*[0-9.]+/)[0].strip

ruby 支持前置条件的正则吗?我在 views 里面写的好像报错。

···ruby /\s?(\d+)/

"Buy a cup for $ 30"[/\$\s*(\d+)/, 1]

"Buy a cup for $ 30".match(/\$\s*([\d.]+)/)[1].strip

"Buy a cup for $ 30, Buy a cup for $30.0, Buy a cup for $ 30.00.".scan(/\$\s*(\d+(?:\.\d+)?)/) do |money|
    puts money[0]
end

不过1..10这样的数字也会被匹配上,ft。。。

#7 楼 @ywjno 这样应该不会匹配 1..10 "Buy a cup for $ 30..52..00".match(/\$\s*(\d+\.{0,1}\d+)/)[1].strip

#8 楼 @zmbacker puts "Buy a cup for $ 30..52..00".match(/\$\s*(\d+\.{0,1}\d+)/)[1].strip # =>30

30..52..00这样的数据不应该让匹配上才对,感觉应该需要加断言才行, 当然可以假定需要处理的数据都是正确的

#9 楼 @ywjno 恩 这些只是我们假定的数据 "..52..00" 实际上他或许已经不是 money 的组成部分了, 比如:$30....... 可能只是表达 30 刀. 想不到的或许还有其它情况,还得看实际需求了。

首先要相信一点,Ruby 1.9 的正则 已经是最强大的了。理论上没有实现不了的。

类似需求我最近刚处理过,当时是希望把我的笔记中所有 `内容' 左右两个符号添加空格分隔,因为无法回溯的缘故,需要用到 Ruby1.9 支持的 子正则表达式, 类似格式:(?>=INNER)

#5 楼 @hooopo

XD, 写法简直太精妙了,酷!

我发现我总是把复杂问题简单化,而我,TNND, 总是把简单问题复杂化。差距啊~

可惜楼主没看到你的答案。

#12 楼 @zw963 嘿嘿,这个问题之后我的正则改了很多遍,最后是这样/[\s\+\$]+[0-9.]+/,然后 gsub 去掉空格还有$。。。比较粗鲁的方法了。。。

#11 楼 @zw963 ruby1.8.7 不支持前置条件替换吧?

#14 楼 @freemem

1.9 only. 1.8 支持后置。

刚看到手册 slice 那一节,刚好 slice 也支持正则 irb(main):050:0> "Buy a cup for $ 30xxxxxx".slice(/\$\s*(\d+)/,1) => "30" 跟 5 楼的实现方式差不多

搭车问个问题,是不是 str[] 等效于 str.slice()

#16 楼 @gaicitadie [] 是 slice 的别名

匿名 #18 2012年05月30日

啊哈,虎跑

#15 楼 @zw963 支持后置也不错,哈哈。

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