我有一个字符串,如“{some | words | are | here}”或“{another | set | of | words}”
所以一般来说,字符串由一个开口的花括号,一个由管道分隔的单词和一个右大括号组成。
获取该字符串中所选单词的最有效方法是什么?
我想做这样的事情:
@my_string = "{this|is|a|test|case}"
@my_string.get_column(0) # => "this"
@my_string.get_column(2) # => "is"
@my_string.get_column(4) # => "case"
get_column方法应该包含什么?
答案 0 :(得分:2)
所以这就是我现在喜欢的解决方案:
class String
def get_column(n)
self =~ /\A\{(?:\w*\|){#{n}}(\w*)(?:\|\w*)*\}\Z/ && $1
end
end
我们使用正则表达式来确保字符串的格式正确,同时抓取正确的列。
正则表达式的解释:
\A
是字符串的开头,\Z
是结尾,所以此正则表达式与enitre字符串匹配。\{
和\}
进行转义,以匹配字符串开头和结尾的花括号。\w
来匹配类似字的字符(包括数字和下划线,但为什么不是)和*
匹配任意数量的。垂直条具有特殊含义,因此我们必须将其作为\|
进行转义。由于我们要对此进行分组,因此我们将其全部包含在非捕获的parens (?:\w*\|)
中(?:
使其无法捕获)。n
之前的列,所以我们告诉正则表达式使用count regex匹配列模式n
次 - 只需在模式后面的花括号中加一个数字。我们使用标准字符串替换,因此我们只需将{#{n}}
表示“与前一个模式完全匹配n
次。(\w*)
(?:\|\w*)*
。捕获列会将其放入$1
,因此如果正则表达式匹配,我们会返回该值。如果没有,我们返回nil,因为这个String没有n
列。
一般情况下,如果您希望列中不只有单词(例如"{a phrase or two|don't forget about punctuation!|maybe some longer strings that have\na newline or two?}"
),那么只需将正则表达式中的所有\w
替换为[^|{}]
,这样您就可以拥有每列包含除花括号或竖条之外的任何内容。
这是我以前的解决方案
class String
def get_column(n)
raise "not a column string" unless self =~ /\A\{\w*(?:\|\w*)*\}\Z/
self[1 .. -2].split('|')[n]
end
end
我们使用类似的正则表达式来确保String包含一组列或引发错误。然后我们从正面和背面剥离花括号(使用self[1 .. -2]
限制从第一个字符开始到倒数第二个字符结束的子字符串),使用管道字符分割列(使用{{1}创建一个列数组),然后找到第n列(使用标准数组查找.split('|')
)。
我想,只要我使用正则表达式验证字符串,我不妨用它来捕获列。