使用正则表达式在 Ruby 中从字符串中提取子字符串

155

在Ruby中如何从字符串中提取子字符串?

示例:

String1 = "<name> <substring>"

我想从String1中提取子字符串(即在最后一次出现的<>之间的所有内容)。

5个回答

359
"<name> <substring>"[/.*<([^>]*)/,1]
=> "substring"
如果我们只需要一个结果,则无需使用scan。当我们拥有Ruby的String[regexp,#]时,就不需要使用Python的match了。
请参考:http://ruby-doc.org/core/String.html#method-i-5B-5D 注意:str [regexp,capture] -> new_str or nil

40
无需贬低其他完全有效(而且我认为更易读)的解决方案。 - coreyward
44
如果他们更好的话,请进行论证。例如,sepp2k的解决方案更加灵活,这就是为什么我在我的解决方案中指出了“如果我们只需要一个结果”的原因。而且,“match()[]”速度较慢,因为它需要两个方法而不是一个。 - Nakilon
6
这是所有方法中最快的,但即使是最慢的方法在我的机器上也只需要4.5微秒。我不想猜测为什么这种方法更快。在性能方面,猜测是毫无用处的。只有实际测量才有意义。 - Wayne Conrad
9
感谢您提供的内容。由于我对 Ruby 不太熟悉,因此我认为这个解决方案更加直接和简洁。谢谢。 - Ryan H.
@Nakilon,这不是我之前注意到的事情,但当然它必须至少有效那么长时间。感谢您对这个问题的回答,它帮助我解决了我的问题。 - Asaf
显示剩余3条评论

150
String1.scan(/<([^>]*)>/).last.first

scan 创建一个数组,对于 String1 中的每个 <item>,它包含在一个元素数组中的 <> 之间的文本(因为当与包含捕获组的正则表达式一起使用时,scan 会创建一个包含每个匹配的捕获结果的数组)。last 给出这些数组中的最后一个,然后 first 给出其中的字符串。


26

你可以很容易地使用正则表达式来实现这个目的...

允许单词周围有空格(但不保留它们):

str.match(/< ?([^>]+) ?>\Z/)[1]

或者不允许空格的情况下:

str.match(/<([^>]+)>\Z/)[1]

1
我不确定最后的 <> 是否真的需要是字符串中的最后一件事。如果允许使用字符串 foo <bar> baz(并且应该得到结果 bar),那么这种方法将无法实现。 - sepp2k
我只是根据他提供的示例字符串进行操作。 - coreyward

12

以下是稍微更加灵活的方法,使用 match 方法。使用它可以提取多个字符串:

s = "<ants> <pants>"
matchdata = s.match(/<([^>]*)> <([^>]*)>/)

# Use 'captures' to get an array of the captures
matchdata.captures   # ["ants","pants"]

# Or use raw indices
matchdata[0]   # whole regex match: "<ants> <pants>"
matchdata[1]   # first capture: "ants"
matchdata[2]   # second capture: "pants"

7
一个更简单的扫描方式是:
String1.scan(/<(\S+)>/).last

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接