perl正则表达式因不明原因而失败

iovurdzv  于 2022-11-15  发布在  Perl
关注(0)|答案(2)|浏览(113)

我尝试用重命名包重命名一些票证,但我只得到返回代码4,没有其他输出或错误。
我已经输入了一些文章,我不是在我的表达中发现问题。
文本模式为:

companyName-mm.yyyy.pdf

我想要的图案

companyName-yyyy.mm.pdf

PS:companyName有5个字母
我尝试了以下命令,但没有成功:

rename 's/(\w{5})-(\d{2}).(\d{4}).*/' 's/$1-$3\.$2\.pdf/' *.pdf
rename 's/(\w{5})-(\d{2}).(\d{4}).*/$1-$3\.$2\.pdf/' *.pdf

没有任何东西被重命名,我得到的只是返回代码4。
有人能告诉我我做错了什么吗?

  • 编辑@zdim:我稍微编辑了OP* 的评论中给出的澄清
qoefvg9y

qoefvg9y1#

rename -n s'/\w+-\K([0-9]{2})\.([0-9]{4})(?=\.pdf)/$2.$1/' *pdf

说明

  • \w+匹配所有连续的“word-characters”,[a-zA-Z0-9_]。因此,根据需要,它在-处停止匹配。如果您希望限制为5个字符,则更改为\w{5}
  • \K会使它丢弃到该点为止的所有匹配项,因此不需要在替换部分中捕获和恢复这些匹配项。
  • 然后捕获两位数和四位数,并在更换部件中进行交换。
  • (?=...)是一个肯定的lookahead,它Assert(只是“看”而不是消费)匹配的数字后面的内容是.pdf
rename -n s'/\w+-\K([0-9]{2})\.([0-9]{4})\.(pdf)/$2.$1.$3/' *pdf

在这里,我没有在pdf之前捕获.,而是将其重新输入,因为我发现这一点看起来更清楚。
检查打印输出后,删除-n以实际重命名。
请注意,该命令在不同的系统中有不同的名称(CentOS上的prename等)。
请参阅perlretut,了解Perl自己的regex教程。
问题中的第一个命令被破坏了,因为s/.../不是一个有效的替换运算符,第二个命令对我来说是有效的,但是.*有潜在的危险:它匹配这两个数字之后的任何内容--不管它是什么,它都用.pdf替换它!

zphenhs4

zphenhs42#

嘿阮!
根据您指定的详细信息,我认为此正则表达式可以解决您的问题:

rename 's/(?<=\w{5}-)(\d{2}).(\d{4})/$2.$1/' *.pdf

它基本上使用lookbehind来不将companyName结果包含在捕获组中,但仍然验证它是否与我们指定的字母字符和长度匹配。
它也不读取“.pdf”,所以在正则表达式的第一部分只捕获了3件事。

  • 0 - mm.yyyy(我们将不使用)
  • 1毫米
  • 2 -年

在捕获这些组并将它们存储到从0开始的索引中之后,我们将替换它们的顺序,因此它们将被替换为"yyyy(2).mm(1)",而不是"mm(1).yyyy(2)"

相关问题