我无法将几个正则表达式压缩为有效的一行。我的文件名的命名如下:Something (0482) - a123b456 - Something [00xcf bxc v32 Something]
.我希望结果是something-a123b456-Something
或something_-_a123b456_-_Something
这是我试图压缩的正则表达式:
's/(^.*)/\L\1/' # makes the whole string lowercase
's/\(.*?\)|_//gs' # removes everything between parentheses
's/\[.*?\]|_//gs' # removes everything between square brackets
's/ /_/g' # substitutes whitespaces with underscores
我尝试将命令链接在一起,无论是手动还是使用这个网站,但正则表达式是不是我的强项。如果有人能告诉我,我真的很感激如何一个将多个命令链接在一起,以便下次我可以自己执行。
prename
顺便说一下,我正在使用(Perl)。
答案1
通常,Perl 表达式与;
so链接在一起,s/.../foo/;s/.../bar/;...
以实现rename
对隐式$_
变量进行操作的样式链接。我不确定你从哪里来的,prename
所以我会用我自己的版本这里的rename
。也许它与你的非常相似。该-p
标志用于预览,或防止损坏文件系统。
$ touch 'Something (0482) - a123b456 - Something [00xcf bxc v32 Something].demo'
$ rename -p 's/(^.*)/\L\1/;s/\(.*?\)|_//gs;s/\[.*?\]|_//gs;s/ /_/g' *.demo
rename Something (0482) - a123b456 - Something [00xcf bxc v32 Something].demo something__-_a123b456_-_something_.demo
然而,这或许可以改进;没有理由对这里的所有内容都使用正则表达式。
$ rename -p '$_=lc; s/\(.*?\)|_//gs;s/\[.*?\]|_//gs; tr/ /_/' *.demo
rename Something (0482) - a123b456 - Something [00xcf bxc v32 Something].demo something__-_a123b456_-_something_.demo
因此,我们将$_=lc
中的所有内容都小写$_
,并将 替换s/ /_/
为tr
。或者也许应该用单个下划线替换连续的空格?如果是这样,s/\s+/_/g
。 and可能还可以改进,尽管在这种平衡表达式上正确匹配会变得更加复杂()
。[]
额外研究s/\(.*?\)|_//gs
没有多大意义;有更好的方法可以杀死_
字符,而无需在()
和[]
杀死表达式中进行(重复!)交替,因此:
$ rename -p '$_=lc; tr/_//; s/\(.*?\)//gs;s/\[.*?\]//gs; tr/ /_/' *.demo
rename Something (0482) - a123b456 - Something [00xcf bxc v32 Something].demo something__-_a123b456_-_something_.demo
通过使用类似“仅匹配不是结束字符的字符”之类的内容可能会提高效率,但您可能更需要可读性而不是效率.*?
。s/\([^)]*\)//gs
但是,如果您在单行代码中使用正则表达式,那么您已经超出了可读性预算。
$ rename -p '$_=lc; tr/_//; s/\([^)]*\)//g; s/\[[^\]]*\]//g; tr/ /_/' *.demo
rename Something (0482) - a123b456 - Something [00xcf bxc v32 Something].demo something__-_a123b456_-_something_.demo