如何使用一行正则表达式获取匹配的内容 [英] how to use one line regular expression to get matched content
问题描述
我是 ruby 的新手,我想知道我是否可以只使用一行代码来完成这项工作.
I'm a newbie to ruby, I want to know if I can use just one line to do the job.
以本网站的搜索"为例.当用户输入 [ruby] regex
时,我可以使用以下代码获取标签和关键字
Take the 'search' of this site for example. When user typed [ruby] regex
, I can use following code to get the tag and keyword
'[ruby] regex' =~ /\[(.*?)\](.*)/
tag, keyword = $1, $2
我们可以一行写吗?
更新
非常感谢!我可以让它变得更难更有趣,输入可能包含多个标签,例如:
Thank you so much! May I make it harder and more interesting, that the input may contains more than one tags, like:
[ruby] [regex] [rails] one line
是否可以使用一行代码来获取标签数组和关键字?我试过了,但失败了.
Is it possible to use one line code to get the tags array and the keyword? I tried, but failed.
推荐答案
您需要 Regexp#match
方法.如果你写 /\[(.*?)\](.*)/.match('[ruby] regex')
,这将返回一个 MatchData
对象.如果我们称该对象为matches
,那么,除其他外:
You need the Regexp#match
method. If you write /\[(.*?)\](.*)/.match('[ruby] regex')
, this will return a MatchData
object. If we call that object matches
, then, among other things:
matches[0]
返回整个匹配的字符串.matches[n]
返回第 n 个捕获组 ($n
).matches.to_a
返回一个由matches[0]
到matches[N]
组成的数组.matches.captures
返回一个只包含捕获组的数组(matches[1]
到matches[N]
).立>matches.pre_match
返回匹配字符串之前的所有内容.matches.post_match
返回匹配字符串之后的所有内容.
matches[0]
returns the whole matched string.matches[n]
returns the nth capturing group ($n
).matches.to_a
returns an array consisting ofmatches[0]
throughmatches[N]
.matches.captures
returns an array consisting of just the capturing group (matches[1]
throughmatches[N]
).matches.pre_match
returns everything before the matched string.matches.post_match
returns everything after the matched string.
方法比较多,对应其他特殊变量等;您可以查看 MatchData
的文档 了解更多信息.因此,在这种特定情况下,您只需要编写
There are more methods, which correspond to other special variables, etc.; you can check MatchData
's docs for more. Thus, in this specific case, all you need to write is
tag, keyword = /\[(.*?)\](.*)/.match('[ruby] regex').captures
<小时>
编辑 1: 好的,对于更难的任务,您将需要 String#scan
方法,它 @Theo 使用;但是,我们将使用不同的正则表达式.以下代码应该可以工作:
Edit 1: Alright, for your harder task, you're going to instead want the String#scan
method, which @Theo used; however, we're going to use a different regex. The following code should work:
# You could inline the regex, but comments would probably be nice.
tag_and_text = / \[([^\]]*)\] # Match a bracket-delimited tag,
\s* # ignore spaces,
([^\[]*) /x # and match non-tag search text.
input = '[ruby] [regex] [rails] one line [foo] [bar] baz'
tags, texts = input.scan(tag_and_text).transpose
input.scan(tag_and_text)
将返回标签-搜索-文本对的列表:
The input.scan(tag_and_text)
will return a list of tag–search-text pairs:
[ ["ruby", ""], ["regex", ""], ["rails", "one line "]
, ["foo", ""], ["bar", "baz"] ]
transpose
调用会翻转它,这样你就有了一个由标签列表和搜索文本列表组成的对:
The transpose
call flips that, so that you have a pair consisting of a tag list and a search-text list:
[["ruby", "regex", "rails", "foo", "bar"], ["", "", "one line ", "", "baz"]]
然后你可以对结果做任何你想做的事情.我可能会建议,例如
You can then do whatever you want with the results. I might suggest, for instance
search_str = texts.join(' ').strip.gsub(/\s+/, ' ')
这会将搜索片段与单个空格连接起来,去除前导和尾随空格,并用单个空格替换多个空格.
This will concatenate the search snippets with single spaces, get rid of leading and trailing whitespace, and replace runs of multiple spaces with a single space.
这篇关于如何使用一行正则表达式获取匹配的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!