需要一些建议。我试图用正则表达式来做一些不可能的事情,如果有可能的话,它就在我的头上。我什么都找不到了。我正试图为我的PDF文件创建一个标签系统。所以如果我有这个文件名:
"csharp 8 in a nutshell[studying programming csharp ebooks].pdf"我希望“”里面的所有单词都有一个“@”。所以上面的文件名如下所示:
"csharp 8 in a nutshell[@studying @programming @csharp @ebooks].pdf"问题是将“@”保留在“”中。例如,我宁愿文件名前面的“csharp”没有“@”。
另外,我正在使用一个名为“散装重命名实用程序”的批量重命名器来帮助我。
谢谢。
发布于 2020-09-10 20:25:25
大容量重命名实用程序不支持替换多个匹配项,只能匹配整个文件名并使用捕获组/反向引用执行替换。
既然您正在使用Windows,我建议您使用Powershell:
cd 'C:\YOUR_FOLDER\HERE'
Get-ChildItem -File | Rename-Item -NewName { $_.Name -replace '(?<=\[[^][]*?)\w+(?=[^][]*])','@$&' } 参见这个regex演示和证明它适用于.NET正则表达式。
(?<=\[[^][]*?) --就在这个位置之前,必须有一个[,然后除了[和]之外,其他任何数量的字符,都要尽可能少。\w+ - 1+字词(?=[^][]*]) -在这个位置之后,必须有除[和]以外的任何数量的字符,尽可能多,然后是一个]字符。替换为@ +整个匹配值($&)。
此外,您也可以使用
Get-ChildItem -File | Rename-Item -NewName { $_.Name -replace '(\G(?!\A)[^][\w]+|\[)(\w+)','$1@$2' }见这个regex演示和.NET正则化试验。
(\G(?!\A)[^][\w]+|\[) -第1组($1):除]、[和word字符之外的前一次匹配和1+字符的结束,或[字符(\w+) -第2组($2):一个或多个单词字符。如果只想重命名*.pdf文件,请用Get-ChildItem *.pdf替换Get-ChildItem -File。
发布于 2020-09-11 00:37:28
我假设最多有一个括号分隔的子字符串。
在使用'@'时,您可以用Perl替换以下正则表达式的零长度匹配(单击"Perl“,然后检查全局选项和情况不同选项)、红宝石、Python的替代正则表达式引擎红宝石、使用perl=true的R或使用PCRE regex引擎的语言(包括PCRE regex引擎)。除了Ruby之外,还需要设置大小写不同(\i)和通用(\g)标志。Ruby只需要案例-淡漠标志。
r = /(?:^.*\[ *|\G(?<!^)|[a-z]+ +)\K(?<=\[| )(?=[a-z][^\[\]]*\])/例如,如果使用Ruby,就会执行
str = "csharp 8 in a nutshell[studying programming csharp ebooks].pdf"
str.gsub(r,'@')
#=> "csharp 8 in a nutshell[@studying @programming @csharp @ebooks].pdf"我相信我上面提到的所有语言都允许从命令行运行一个简短的脚本。(下面我提供了一个Ruby脚本。)
regex引擎执行以下操作。
(?: : begin non-capture group
^.*\[ * : match beginning of string then 0+ characters then '['
then 0+ spaces
| : or
\G : asserts the position at the end of the previous match
or at the start of the string for the first match
(?<!^) : use a negative lookbehind to assert that the current
location is not the start of the string
| : or
[a-z]+ + : match 1+ letters then 1+ spaces
) : end non-capture group
\K : reset beginning of reported match to current location
and discard all previously-matched characters from match
to be returned
(?<= : begin positive lookbehind
\[|[ ] : match '[' or a space
) : end positive lookbehind
(?= : begin positive lookahead
[a-z][^\[\]]*\] : match a letter then 0+ characters other than '[' and ']'
then ']'
) : end positive lookahead另一种可能性(用Ruby说明)是将字符串分成三部分,修改中间的部分,然后重新加入这些片段:
first, mid, last = str.split /(?<=\[)|(?=\])/
#=> ["csharp 8 in a nutshell[",
# "studying programming csharp ebooks",
# "].pdf"]
first + mid.gsub(/(?<=\A| )(?! )/,'@') + last
#=> "csharp 8 in a nutshell[@studying @programming @csharp @ebooks].pdf"split使用的正则表达式是:“匹配一个(零宽度)字符串,该字符串前面是'[' ((?<=\[)是一个正的查找),或者是']' ((?=\])是一个正的查找)。”通过匹配零宽度字符串split,split不会删除任何字符。
gsub的regex表示,“匹配一个零宽度字符串,该字符串位于字符串的开头,或前面有一个空格,后面跟着一个空格以外的字符((?! )是一个负前瞻)。它也可以写为/(?<![^ ])(?! )/ ((?<![^ ])表示负查找)。”
变体:
first + mid.split.map { |s| '@' + s }.join(' ') + last
#=> "csharp 8 in a nutshell[@studying @programming @csharp @ebooks].pdf"我创建了一个名为'in'的文件,其中包含以下两行:
Little [Miss Muffet sat on her] tuffet
eating her [curds and] whey下面是一个(Ruby)脚本的示例,它可以从命令行运行以执行必要的替换。
ruby -e "File.open('out', 'w') do |fout|
File.foreach('in') do |str|
first, mid, last = str.split(/(?<=\[)|(?=\])/)
fout.puts(first + mid.gsub(/(?<=\A| )(?! )/,'@') + last)
end
end"这将生成一个名为'out'的文件,其中包含以下两行:
Little [@Miss @Muffet @sat @on @her] tuffet
eating her [@curds @and] wheyhttps://stackoverflow.com/questions/63836286
复制相似问题