使用正则表达式从Ruby中的字符串中提取子字符串
如何从Ruby中的字符串中提取子字符串 例如:使用正则表达式从Ruby中的字符串中提取子字符串,ruby,regex,string,substring,Ruby,Regex,String,Substring,如何从Ruby中的字符串中提取子字符串 例如: String1 = "<name> <substring>" String1=“” 我想从String1中提取substring(即上次出现的)中的所有内容。String1.scan(/]*)>/).last.first scan为String1中的每个创建一个数组,该数组包含单元素数组中和之间的文本(因为当与包含捕获组的正则表达式一起使用时,scan会创建一个包含每个匹配的捕获的数组)last给出这些数组中的最后一个
String1 = "<name> <substring>"
String1=“”
我想从String1
中提取substring
(即上次出现的
)中的所有内容。String1.scan(/]*)>/).last.first
scan
为String1
中的每个
创建一个数组,该数组包含单元素数组中
和
之间的文本(因为当与包含捕获组的正则表达式一起使用时,scan会创建一个包含每个匹配的捕获的数组)last
给出这些数组中的最后一个,然后首先给出其中的字符串。您可以很容易地使用正则表达式来实现这一点
允许单词周围有空格(但不保留):
str.match(/<?([^>]+)?>\Z/)[1]
或没有允许的空间:
str.match(/<([^>]+)>\Z/)[1]
str.match(/]+)>\Z/)[1]
”[/.]*)/,1]
=>“子字符串”
如果我们只需要一个结果,则无需使用scan
。
当我们使用Ruby的字符串[regexp,#]
时,不需要使用Python的match
见:
注:str[regexp,capture]→ 新的_str或nil
这里有一个使用匹配
方法的更灵活的方法。使用此选项,您可以提取多个字符串:
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"
s=“”
matchdata=s.match(/]*)>]*)>/)
#使用“捕获”获取捕获的数组
matchdata.captures#[“蚂蚁”,“裤子”]
#或者使用原始索引
matchdata[0]#整个正则表达式匹配:“
matchdata[1]#首次捕获:“蚂蚁”
matchdata[2]#第二个捕获:“裤子”
更简单的扫描是:
String1.scan(/<(\S+)>/).last
String1.scan(//).last
我不确定最后一个
是否应该是字符串中的最后一个内容。例如,如果允许使用字符串foo baz
(并且应该给出结果bar
),这将不起作用。我只是根据他提供的示例字符串来做的。没有必要怀疑其他完全有效(并且我可能认为更可读)的解决方案。@coreyward,如果它们更好,请进行论证。例如,sepp2k的解决方案更灵活,这就是为什么我在解决方案中只需要一个结果时指出。而match()[]
速度较慢,因为它是两种方法而不是一种。这是所有方法中最快的一种,但在我的机器上,即使是最慢的方法也只需要4.5微秒。我不想猜测为什么这种方法更快。在表现上,投机是无用的。我发现这个解决方案更直接、更切题(因为我是Ruby新手)。谢谢。@Nakilon在考虑产品和团队的整体成功时,可读性可能会超过微小的性能差异,因此coreyward的评论是正确的。也就是说,我认为在这个场景中,string[regex]
同样可读,所以这就是我个人使用的。
"<name> <substring>"[/.*<([^>]*)/,1]
=> "substring"
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"
String1.scan(/<(\S+)>/).last