【发布时间】:2014-07-01 15:17:28
【问题描述】:
如何使用正则表达式获取“ratings-small star rating-4 field_stars_rating csm_review”之类的字符串,而使用 gsub 只返回“rating-4”,其中 4 可以是任何数字?我使用的任何东西都只替换部分位
【问题讨论】:
如何使用正则表达式获取“ratings-small star rating-4 field_stars_rating csm_review”之类的字符串,而使用 gsub 只返回“rating-4”,其中 4 可以是任何数字?我使用的任何东西都只替换部分位
【问题讨论】:
gsub 在这里是错误的选择。这样做会更有意义:
"ratings-small star rating-4 field_stars_rating csm_review".match(/\brating-\d\b/).to_s
因为您正在寻找字符串的特定部分,所以直接搜索它更有意义。
要获取连字符后的数字,请使用:
"ratings-small star rating-4 field_stars_rating csm_review".match(/\brating-(\d)\b/)[0]
【讨论】:
\b 匹配一个空格。至于获取号码,请参阅我的编辑。
\b 匹配“单词边界”。它查找:^\w(行首,后跟一个字符)、\w$(行尾,前面是一个字符)、\w\W(一个单词字符后跟一个非单词字符)或@ 987654330@(非单词字符后跟单词字符)。单词字符被定义为字母、数字和少数几个符号,在\brating-中使用时,它确保“rating”中的r在单词的前面(而不是在单词中,比如crating、abracadabrating等等)。
由于您试图保留字符串的一部分,而不是考虑如何删除其他任何内容以仅留下有趣的部分,您应该考虑如何提取字符串的相关部分。我会选择带有正则表达式参数的String#[] 方法:
string = "ratings-small star rating-4 field_stars_rating csm_review"
string[/\brating-\d\b/]
# => "rating-4"
【讨论】:
与其尝试替换直到单词的位置或要匹配的数字的位置之后的所有内容,更好的方法是在整个字符串中使用 match 该子模式。
string.match(/\b[a-z]+-\d+\b/i)
说明:
单词边界不消耗任何字符。它断言一方面有一个单词字符,另一方面没有。
\b # the boundary between a word char (\w) and not a word char
[a-z]+ # any character of: 'a' to 'z' (1 or more times)
- # '-'
\d+ # digits (0-9) (1 or more times)
\b # the boundary between a word char (\w) and not a word char
【讨论】:
我不会为此使用纯正则表达式,因为它会让人很难阅读:
string = "ratings-small star rating-4 field_stars_rating csm_review"
string.split.select {|s| s =~ /^rating-\d$/}.join(' ')
如果您只期望一个元素:
string[/\brating-\d\b/]
【讨论】:
string[/(rating-\d+)/, 1]。