我的输入*INI
文件:
\nleftarrow = {\not\leftarrow}
\nrightarrow = {\not\rightarrow}
\nleftrightarrow = {\not\leftrightarrow}
我需要找到\not\leftarrow
并替换为字符串\nleftarrow
。事情就在这里\not\leftarrow
我们需要检查查找字符串中是否有空格,例如:\not \leftarrow
。我们需要替换字符串的两件事。
在主文件中:
$str=~s/\\not\\leftarrow/\\nleftarrow/g;
$str=~s/\\not \\leftarrow/\\nleftarrow/g;
我的代码:
foreach my $repStr(@tags) #storing all the `*INI` lines in the Array
{
my ($findStr, $replaceStr) = ($repStr =~ /^([^\s]*)\s*=\s*\{([^\{\}]*)\}/i);
$str=~s/$replaceStr/$findStr/g;
#I need to check the string with space
}
任何人都可以指导我对代码进行编码的方式。
答案 0 :(得分:1)
您可以使用命令组合创建单个命令数组:my @cmds = $replaceStr =~ /\\[^\\]+/g
。然后使用两者之间的可选空格加入它们:join '\s*', @cmds
但是,您还需要转义$replaceStr
的特殊字符(如反斜杠),否则它们会在正则表达式中打扰您。您可以使用quotemeta
内置功能执行此操作。 (也可以使用\Q...\E
在正则表达式内部完成此操作,但由于此处您不希望转义\s*
,quotemeta
会更方便。
放在一起,它变成了:
my @cmds = $replaceStr =~ /\\[^\\]+/g
my @esc_cmds = map { quotemeta } @cmds;
my $re = join '\s*', @esc_cmds;
但是你可以将它组合成一行(如果它对你来说足够可读):
my $re = join '\s*', map { quotemeta } ($replaceStr =~ /\\[^\\]+/g);
例如,此脚本以您希望的方式工作:
use strict;
use warnings;
use feature 'say';
my @tags = ( '\nleftarrow = {\not\leftarrow}',
'\nrightarrow = {\not\rightarrow}',
'\nleftrightarrow = {\not\leftrightarrow}' );
# Only the last 2 lines should be left unchanged
my $str = '\not\leftarrow
\not \leftarrow
\not\leftarrow
\ not\leftarrow
\leftarrow';
say "Before:\n$str";
foreach my $repStr(@tags) {
my ($findStr, $replaceStr) = ($repStr =~ /^([^\s]*)\s*=\s*\{([^\{\}]*)\}/i);
my $re = join '\s*', map { quotemeta } ($replaceStr =~ /\\[^\\]+/g);
$str =~ s/$re/$findStr/g;
}
say "\nAfter:\n$str";
答案 1 :(得分:1)
为了解决问题,我们给出了以下内容:
这将TeX / LaTeX宏名称映射到TeX / LaTeX命令序列。它是macro name = command sequence
格式。 E.g:
\nleftarrow = {\not\leftarrow}
\nrightarrow = {\not\rightarrow}
\nleftrightarrow = {\not\leftrightarrow}
不清楚包含替换的括号是什么功能。它们是否出现在源文件中(见下文)?或者,他们划分空格吗?简而言之,他们应该被剥夺吗?
如果您只提供一段示例文本而不是要求我们对其进行假设,情况会好得多。
在此,有一些命令序列需要根据上述配置文件中的映射用宏名称替换。但是,because TeX eats spaces after macro invocations,需要考虑替换序列中每个命令之间空格字符的可能性。在上面的例子中,每个替换序列中只有两个命令,但不难想象更多。
如果您只提供一段示例文本而不是要求我们构建它,情况会好得多。
您似乎已经制定了一种解析替换映射的自定义方法。我建议使用一个像样的解析器,例如Config::INI::Reader
#!/usr/bin/env perl
use strict;
use warnings;
use Config::INI::Reader;
my $ini_contents = <<'EO_INI';
\nleftarrow = {\not\leftarrow}
\nrightarrow = {\not\rightarrow}
\nleftrightarrow = {\not\leftrightarrow}
EO_INI
my $tex_source = <<'EO_TEX';
Lorem ipsum dolor \not\leftarrow{} sit amet, ea quem idque senserit eum, in
\not \rightarrow{} duo amet recusabo sensibus. Mei velit suavitate ei, ferri
consequuntur vis eu, qui unum volumus an. Rebum democritum no nec, et \not
\leftrightarrow{} eam natum patrioque, mentitum evertitur reprimique nec te.
Usu et docendi \not\rightarrow{} partiendo, eos ut assum errem simul.
EO_TEX
# Helper function to deal with matches with spaces
# because our mapping does not have sequences
# containing spaces.
sub match_to_key {
my ($s) = @_;
$s =~ s/\s+//g;
return $s;
}
# Assume mappings appear in a single global section only
my $macro_definition = Config::INI::Reader->read_string($ini_contents)->{_};
# Assuming { and } need to be removed
for (values %$macro_definition) {
s/^\{//;
s/\}\z//;
}
# map command sequences to replacement macros
$macro_definition = { reverse %$macro_definition };
my $command_sequence_pat = join '|',
sort { length($b) <=> length($a) }
map join('\s?', map quotemeta, m{ (\\\w+) }gx),
keys %$macro_definition
;
print "Text before replacement:\n";
print ">>>$tex_source<<<\n\n";
$tex_source =~ s/($command_sequence_pat)/$macro_definition->{match_to_key($1)}/g;
print "Text after replacement:\n";
print ">>>$tex_source<<<\n\n";
请注意,原始文本的包装可能会搞砸。
输出:
Text before replacement:
>>>Lorem ipsum dolor \not\leftarrow{} sit amet, ea quem idque senserit eum, in
\not \rightarrow{} duo amet recusabo sensibus. Mei velit suavitate ei, ferri
consequuntur vis eu, qui unum volumus an. Rebum democritum no nec, et \not
\leftrightarrow{} eam natum patrioque, mentitum evertitur reprimique nec te.
Usu et docendi \not\rightarrow{} partiendo, eos ut assum errem simul.
<<<
Text after replacement:
>>>Lorem ipsum dolor \nleftarrow{} sit amet, ea quem idque senserit eum, in
\nrightarrow{} duo amet recusabo sensibus. Mei velit suavitate ei, ferri
consequuntur vis eu, qui unum volumus an. Rebum democritum no nec, et \nleftrightarrow{} eam natum patrioque, mentitum evertitur reprimique nec te.
Usu et docendi \nrightarrow{} partiendo, eos ut assum errem simul.
<<<