如何将多个正则表达式压缩为一行?

如何将多个正则表达式压缩为一行?

我无法将几个正则表达式压缩为有效的一行。我的文件名的命名如下:Something (0482) - a123b456 - Something [00xcf bxc v32 Something].我希望结果是something-a123b456-Somethingsomething_-_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

相关内容