Regex 如何更改文件名中除最后N个字符以外的所有字符的大小写

Regex 如何更改文件名中除最后N个字符以外的所有字符的大小写,regex,perl,Regex,Perl,使用Perl和重命名,我希望更改为小写或大写,除了文件名中的最后N个字符 例如,如果N为10且需要大写,则 foo\u 1\u bar\u 2-abcdef.txt应该变成foo\u 1\u bar\u 2-abcdef.txt 我尝试过类似于rename“y/a-z{.10}$/a-z/”*,但是y操作符似乎不想接受{.10},我认为这是因为你不理解y/在做什么 这是一种基于字符的替换,所以你可以从a-z->a-z中说“音译” 在这种情况下,{.10}只是另一组要替换的字符(但左侧没有匹配项)

使用Perl和
重命名
,我希望更改为小写或大写,除了文件名中的最后N个字符

例如,如果N为10且需要大写,则
foo\u 1\u bar\u 2-abcdef.txt
应该变成
foo\u 1\u bar\u 2-abcdef.txt


我尝试过类似于
rename“y/a-z{.10}$/a-z/”*
,但是
y
操作符似乎不想接受
{.10}

,我认为这是因为你不理解
y/
在做什么

这是一种基于字符的替换,所以你可以从a-z->a-z中说“音译”

在这种情况下,
{.10}
只是另一组要替换的字符(但左侧没有匹配项)

为了更清楚地说明发生了什么:

y/a-z{.10}$/A-Zlmnopq/;
在您的字符串上,将使其:

FOO_n_BAR_2-ABCDEFmTXT
因为“0”和“1”正在映射到字符

但要想做你想做的事,你可以这样处理:

 s/(.*)(.{10})/uc ($1).$2/e;
例如:

尽管您可能会发现使用分隔符锚定(例如
-text
)更好/更整洁,因为这似乎是您的目标。(我猜是这样的):


我认为这是因为你不理解
y//
在做什么

这是一种基于字符的替换,所以你可以从a-z->a-z中说“音译”

在这种情况下,
{.10}
只是另一组要替换的字符(但左侧没有匹配项)

为了更清楚地说明发生了什么:

y/a-z{.10}$/A-Zlmnopq/;
在您的字符串上,将使其:

FOO_n_BAR_2-ABCDEFmTXT
因为“0”和“1”正在映射到字符

但要想做你想做的事,你可以这样处理:

 s/(.*)(.{10})/uc ($1).$2/e;
例如:

尽管您可能会发现使用分隔符锚定(例如
-text
)更好/更整洁,因为这似乎是您的目标。(我猜是这样的):


除了
s//
解决方案之外,这似乎也是一项简单的工作:


除了
s//
解决方案之外,这似乎也是一项简单的工作:


我更喜欢使用
\U
转义序列,而不是
uc
,以及替换的表达式模式。向前看也不需要重新合并字符串的未更改部分

use strict;
use warnings 'all';
use feature 'say';

my $s = join '', 'a' .. 'z';

$s =~ s/(.+)(?=.{10})/\U$1/;

say $s;
输出 但是,如果您的文件名始终是给定形式的,即您始终希望在连字符之前使用大写字母,那么您应该根据上下文进行操作,而不是计算字符数以保持不变

use strict;
use warnings 'all';
use feature 'say';

my $s = 'foo_1_bar_2-abcdef.txt';

$s =~ s/^([^-]+)/\U$1/;

say $s;
输出
我更喜欢使用
\U
转义序列,而不是
uc
,以及替换的表达式模式。向前看也不需要重新合并字符串的未更改部分

use strict;
use warnings 'all';
use feature 'say';

my $s = join '', 'a' .. 'z';

$s =~ s/(.+)(?=.{10})/\U$1/;

say $s;
输出 但是,如果您的文件名始终是给定形式的,即您始终希望在连字符之前使用大写字母,那么您应该根据上下文进行操作,而不是计算字符数以保持不变

use strict;
use warnings 'all';
use feature 'say';

my $s = 'foo_1_bar_2-abcdef.txt';

$s =~ s/^([^-]+)/\U$1/;

say $s;
输出
你认为
{.10}
在这种情况下应该做什么?因为
y/
是基于字符的…我想知道如果它是正则表达式模式会发生什么!你认为
{.10}
应该在这种情况下做什么?因为
y/
是基于字符的…我想知道如果它是正则表达式模式会发生什么!事实上,在看过
重命名-f'y/a-Z/a-Z/'*
更改大小写和
s/foo/bar/
这样的事情之后,我没有将两者联系起来。从我所看到和理解的情况来看,(.*-)意思是“之前的所有字符-”?事实上,在看过类似于
rename-f'y/A-Z/A-Z/'*
以更改大小写和
s/foo/bar/
以进行替换之后,我没有将两者联系起来。从我所看到和理解的情况来看,(.-)表示“之前的所有字符-”,感谢您的回答,
\U
也以更好的方式处理unicode。感谢您的回答,
\U
也以更好的方式处理unicode。
FOO_1_BAR_2-abcdef.txt