如何理解gsub(/^.*,//,”)或正则表达式
分解下面的代码来理解我的正则表达式和gsub
理解:
str = "abc/def/ghi.rb" str = str.gsub(/^.*\//, '') #str = ghi.rb
^
:字符串的开头
\/
:转义字符为/
^.*\/
:字符串中从^.*\/
开始到最后一次出现的所有内容
我对表达的理解是对的吗?
.*
如何正常工作?
您的一般理解是正确的。 整个正则表达式将匹配abc/def/
和String#gsub
将用空字符串替换它。
但是,请注意String#gsub
不会更改字符串。 这意味着str
将在替换后包含原始值( "abc/def/ghi.rb"
)。 要在适当的位置更改它,您可以使用String#gsub!
。
至于.*
如何工作 – 正则表达式引擎使用的算法称为回溯 。 因为.*
是贪婪的(会尝试匹配尽可能多的字符),你可以认为这样的事情会发生:
第1步 :
.*
匹配整个字符串abc/def/ghi.rb
之后\/
尝试匹配正斜杠,但失败(没有任何东西可以匹配)。.*
必须回溯。
第2步 :.*
匹配除最后一个字符之外的整个字符串 –abc/def/ghi.r
之后\/
尝试匹配正斜杠,但失败(/ != b
)。.*
必须回溯。
第3步 :.*
匹配除最后两个字符之外的整个字符串 –abc/def/ghi.
。 之后\/
尝试匹配正斜杠,但失败(/ != r
)。.*
必须回溯。
…
步骤n :.*
匹配abc/def
。 之后\/
尝试匹配正斜杠并成功。 匹配在这里结束。
不,不完全。
-
^
:一行的开头 -
\/
:转义斜杠(转义字符是\
单独) -
^.*\/
:从一行的开头到字符串中最后一次出现的所有内容
.*
取决于正则表达式的模式。 在单行模式下(即,没有m
选项),它表示零或更多非换行符的最长可能序列。 在多线模式下(即使用m
选项),它表示零个或多个字符的最长可能序列。
您的理解是正确的,但您还应注意最后一条陈述是正确的,因为:
Repetition is greedy by default: as many occurrences as possible are matched while still allowing the overall match to succeed.
引自Regexp文档。
是。 简而言之,它匹配以文字/
( \/
)结尾的任意数量的任何字符( .*
)。
gsub
用第二个参数替换匹配(空字符串''
)。
你的正则表达式没有错,但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 # => "/"
如果您的代码从一个系统移动到另一个系统,如果您使用内置方法,它将继续工作,而使用正则表达式将立即中断,因为分隔符将是错误的。