如何理解gsub(/^.*,//,'')或正则表达式

时间:2015-12-21 11:50:24

标签: ruby regex gsub

分解以下代码以了解我的正则表达式和gsub理解:

str = "abc/def/ghi.rb"
str = str.gsub(/^.*\//, '')
#str = ghi.rb

^:字符串的开头

\//

的转义字符

^.*\/:字符串

中从/开始到最后一次出现的所有内容

我对表达的理解是对吗?

.*如何正常工作?

5 个答案:

答案 0 :(得分:4)

您的一般理解是正确的。整个正则表达式将匹配abc/def/,而String#gsub将替换为空字符串。

但是,请注意String#gsub不会更改字符串。这意味着str将包含替换后的原始值("abc/def/ghi.rb")。要对其进行更改,您可以使用String#gsub!

<小时/> 至于.*如何工作 - 正则表达式引擎使用的算法称为backtracking。由于.*是贪婪的(会尝试匹配尽可能多的字符),你可以认为这样的事情会发生:

  

第1步.*匹配整个字符串abc/def/ghi.rb。之后\/尝试匹配正斜杠,但失败(没有任何东西可以匹配)。 .*必须回溯   第2步.*匹配除最后一个字符之外的整个字符串 - abc/def/ghi.r。之后\/尝试匹配正斜杠,但失败(/ != b)。 .*必须回溯   第3步.*匹配除最后两个字符之外的整个字符串 - abc/def/ghi.。之后\/尝试匹配正斜杠,但失败(/ != r)。 .*必须回溯   的 ...
  第n步.*匹配abc/def。之后\/尝试匹配正斜杠并成功。匹配在这里结束。

答案 1 :(得分:2)

不,不完全。

  • ^:行开头
  • \/:转义斜杠(转义字符仅为\
  • ^.*\/:从一行的开头到字符串中最后一次出现/的所有内容

.*取决于正则表达式的模式。在单行模式中(即,没有m选项),它表示零或更多非换行符的最长可能序列。在多行模式下(即使用m选项),它表示零个或多个字符的最长序列。

答案 2 :(得分:1)

您的理解是正确的,但您还应注意最后一条陈述是正确的,因为:

Repetition is greedy by default: as many occurrences as possible 
are matched while still allowing the overall match to succeed. 

引自Regexp文档。

答案 3 :(得分:0)

是。简而言之,它匹配以文字.*/)结尾的任意数量的任何字符(\/)。

gsub将匹配替换为第二个参数(空字符串'')。

答案 4 :(得分:0)

  

你的正则表达式没有错,但File.basename(str)可能更合适。

要阐述@Stefen所说的内容:看起来你正在处理一个文件路径,这会让你的问题成为一个XY问题,当你问X时应该问Y:而不是如何使用和理解正则表达式,问题应该是使用什么工具来管理路径。

使用已经编写的语言附带的代码,而不是滚动自己的代码:

str = "abc/def/ghi.rb"
File.basename(str) # => "ghi.rb"
File.dirname(str) # => "abc/def"
File.split(str) # => ["abc/def", "ghi.rb"]

您希望利用File的内置代码的原因是它考虑了* nix风格的操作系统和Windows中的目录分隔符之间的区别。在启动时,Ruby会检查操作系统并将File::SEPARATOR常量设置为操作系统所需的内容:

File::SEPARATOR # => "/"

如果您的代码从一个系统移动到另一个系统,如果您使用内置方法,它将继续工作,而使用正则表达式将立即中断,因为分隔符将是错误的。