首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用标准重命名文件

用标准重命名文件
EN

Stack Overflow用户
提问于 2020-09-10 19:13:25
回答 2查看 76关注 0票数 1

需要一些建议。我试图用正则表达式来做一些不可能的事情,如果有可能的话,它就在我的头上。我什么都找不到了。我正试图为我的PDF文件创建一个标签系统。所以如果我有这个文件名:

代码语言:javascript
复制
"csharp 8 in a nutshell[studying programming csharp ebooks].pdf"

我希望“”里面的所有单词都有一个“@”。所以上面的文件名如下所示:

代码语言:javascript
复制
"csharp 8 in a nutshell[@studying @programming @csharp @ebooks].pdf"

问题是将“@”保留在“”中。例如,我宁愿文件名前面的“csharp”没有“@”。

另外,我正在使用一个名为“散装重命名实用程序”的批量重命名器来帮助我。

  1. 这能办到吗?
  2. 如果可以的话,有什么暗示吗?

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-10 20:25:25

大容量重命名实用程序不支持替换多个匹配项,只能匹配整个文件名并使用捕获组/反向引用执行替换。

既然您正在使用Windows,我建议您使用Powershell:

代码语言:javascript
复制
cd 'C:\YOUR_FOLDER\HERE'
Get-ChildItem -File | Rename-Item -NewName { $_.Name -replace '(?<=\[[^][]*?)\w+(?=[^][]*])','@$&' } 

参见这个regex演示证明它适用于.NET正则表达式

  • (?<=\[[^][]*?) --就在这个位置之前,必须有一个[,然后除了[]之外,其他任何数量的字符,都要尽可能少。
  • \w+ - 1+字词
  • (?=[^][]*]) -在这个位置之后,必须有除[]以外的任何数量的字符,尽可能多,然后是一个]字符。

替换为@ +整个匹配值($&)。

此外,您也可以使用

代码语言:javascript
复制
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

票数 1
EN

Stack Overflow用户

发布于 2020-09-11 00:37:28

我假设最多有一个括号分隔的子字符串。

在使用'@'时,您可以用Perl替换以下正则表达式的零长度匹配(单击"Perl“,然后检查全局选项和情况不同选项)、红宝石、Python的替代正则表达式引擎红宝石、使用perl=true的R或使用PCRE regex引擎的语言(包括PCRE regex引擎)。除了Ruby之外,还需要设置大小写不同(\i)和通用(\g)标志。Ruby只需要案例-淡漠标志。

代码语言:javascript
复制
r = /(?:^.*\[ *|\G(?<!^)|[a-z]+ +)\K(?<=\[| )(?=[a-z][^\[\]]*\])/

例如,如果使用Ruby,就会执行

代码语言:javascript
复制
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引擎执行以下操作。

代码语言:javascript
复制
(?:                : 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说明)是将字符串分成三部分,修改中间的部分,然后重新加入这些片段:

代码语言:javascript
复制
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使用的正则表达式是:“匹配一个(零宽度)字符串,该字符串前面是'[' ((?<=\[)是一个正的查找),或者是']' ((?=\])是一个正的查找)。”通过匹配零宽度字符串splitsplit不会删除任何字符。

gsub的regex表示,“匹配一个零宽度字符串,该字符串位于字符串的开头,或前面有一个空格,后面跟着一个空格以外的字符((?! )是一个负前瞻)。它也可以写为/(?<![^ ])(?! )/ ((?<![^ ])表示负查找)。”

变体:

代码语言:javascript
复制
first + mid.split.map { |s| '@' + s }.join(' ') + last
  #=> "csharp 8 in a nutshell[@studying @programming @csharp @ebooks].pdf"

我创建了一个名为'in'的文件,其中包含以下两行:

代码语言:javascript
复制
Little [Miss Muffet sat on her] tuffet
eating her [curds and] whey

下面是一个(Ruby)脚本的示例,它可以从命令行运行以执行必要的替换。

代码语言:javascript
复制
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'的文件,其中包含以下两行:

代码语言:javascript
复制
Little [@Miss @Muffet @sat @on @her] tuffet
eating her [@curds @and] whey
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63836286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档