Perl 正则表达式匹配撇号失败

Perl 正则表达式匹配撇号失败

我正在尝试编写一个 Perl 脚本来将多个脚本转换为规范形式。我期待剧本

#!/usr/bin/perl -W
use File::Spec;
use Getopt::Long 2.3203 qw(:config auto_help auto_version);
use IO::File;
my  $base = '[A-Z]|\\\w+\{[A-Z]\}';
my  $tag  = '[a-z]|\{[A-Z]\+1\}|\\[A-Z]+';
my  $sub  = '_(?:$tag)';
my  $sup  = '[\']?(?:\^$tag)?';
my  $term = "$base(?:$sup)?(?:$sub)?";
my  $fbtb = qr/(\\Id)\^\{($term)\}_\{($term)\}/ix;
my  $ft   = qr/(\\Id)\^($term)_($term)/ix;
my  $t    = qr/(\\Id)_($term)/ix;
my  $btt  = qr/(\\Id)_\{($term),($term)\}/ix;
my  $bt   = qr/(\\Id)_\{($term)\}/ix;
my  $bpt  = qr/(\\Id)_\{($term(?:,$term)+)\}/ix;
my  $t1   = "\1\[\{\2\}\]";
my  $t2   = "\1\[\{\2\},\{\3\}\]";
while (my $ifn=shift) {
  my $ofn = $ifn.'new';
  my ($ifh,$ofh);
  open IFH,'<',$ifn or die "Unable to open $ifn for input\n";
  open OFH,'>',$ofn or die "Unable to open $ofn for output\n";
  while (<IFH>) {
    m/(\\Id)_{($base(?:$sup)),($base')/ix
      and print STDOUT "Match 1 $&\n";
    m/(\\Id)_{($base)/ix
      and print STDOUT "Match 2 $&\n";
    m/(\\Id)_{([A-Z]|\\\w+\{[A-Z]\}\^$tag)/ix
      and print STDOUT "Match 3 $&\n";
    s/$fbtb/$t2/ix
      and print STDOUT "Changed $&\n";
    s/$ft/$t2/ix
      and print STDOUT "Changed $&\n";
    s/$btt/$t2/ix
      and print STDOUT "Changed $&\n";
    s/$bpt/$t1/ix
      and print STDOUT "Changed $&\n";
    s/$bt/$t1/ix
      and print STDOUT "Changed $&\n";
    s/$t/$t1/ix
      and print STDOUT "Changed $&\n";
    print OFH;
  }
}

匹配下面数据中的所有行,但无法匹配撇号后跟大括号。

$\seqname{R} = \Range(\funcseqname{f})$. Then $ID_\seqname{R}$ is a left
$\compose[()]$ identity for $\funcseqname{f}$ and $ID_\seqname{D}$ is a
$\funcname{f} \maps S \to T' \defeq \Id_{T,T'} \compose \funcname{f}$
the inclusion map $\Id_{A',A} \maps A' \hookrightarrow A$ is a
$\Id_{\seqname{S}^i,\seqname{S}^{i+1}}$ is open and continuous, hence
The inclusion map $\Id_{A'} \maps A' \hookrightarrow A$ is continuous.
      \Id_{S^1_{\alpha_\beta}, S^2_{\alpha_\beta}}
Then $\ID_{\seqname{S}}$ $\Sigma$-commutes with
and $\ID[{\seqname{S}}] = \ID_{\seqname{S},\seqname{S}}$.
$\Id_{S^1_\alpha,S^2_\alpha} \arin \catname{S}^2_\alpha$ and
$\Id_{S_\alpha,S_\alpha} = \Id[{S_\alpha}] \arin \catname{S}_\alpha$ and
  \ID_{(E^1,\seqname{C}^1),(E^2,\seqname{C}^2)},
$\Id_{I.U^2}$ is a morphism of $\seqname{E}^2$. Then define
containing $u^1$. $\Id_{U,\seqname{E}^1}$ is a morphism of
$\catname{E}^1 \subcat[full-] \catname{E}^2$, $\Id_{U,\seqname{E}^1}$ is
is $\Id_{(\seqname{A}^i, \seqname{E}^i, \seqname{C}^i}$.
is $\Id_{(\seqname{A}^i, \seqname{E}^i, \seqname{C}^i}$.
$\Id_{(\seqname{A}^i, \seqname{E}^i, \seqname{C}^i}$.
    (\Id_{\pi_1(\seqname{E}^i)}, \Id_{\pi_1(\seqname{C}^i)}),
\Id_{\Functor^\Ck_{\M,\Ck} (\seqname{A}^i, \seqname{E}^i, \seqname{C}^i)}
%\Id[{\seqname{L}^1}] = \Id_{\Functor^{\Ck,\catseqname{M}}_{\Man,\LCS}(\seqname{S}^i)}
   \bigl ( \Id[{\Triv{E^i}}], \Id_{\Triv[\Ck-]{C^i}} \bigr ),
$\Id_{(\seqname{A}^i, \seqname{E}^i, \seqname{C}^i}$ is an identity
    (\Id_{\Triv{E^i}}, \Id[C^i]),
    (\Id_{\Triv{E^i}}, \Id[C^i]),
    (\Id_{\Triv{E^i}}, \Id[C^i]),
    (\Id_{\Triv{E^i}}, \Id[C^i]),
$\Bun \seqname{B}$ is a category and $Id_{B^\alpha}$ is the identity

答案1

不要使用字符串来构建正则表达式,请使用qr//.有一个重要的区别:当由 创建的两个正则表达式qr//连接时,每个正则表达式首先被包装在(?:...).当两个字符串连接时,您只会得到一个包含第一个字符串和第二个字符串的字符串。但$base包含一个管道符号,其范围将受到封闭的(?:...).比照。

my $s = "A',";
my $r = 'A|\{';

print $s =~ $_ ? 1 : 0
    for qr/$r,/,      # 1
        qr/(?:$r),/;  # 0

此外,使用包含变量名称的变量不会在正则表达式中插入第二个变量,只发生一级插值:

my $r = 'A';
my $s = '$r';
print "A" =~ /$s/;  # Doesn't match.

此外,\1在双引号字符串中(替换中的替换行为类似于双引号字符串)意味着chr(1). Perl 用于$1引用第一个匹配组。但同样,使用包含的变量$1不会扩展它,因为只发生一级插值。

my $s = 'ABC';
my $r = '$1';
say $s =~ s/(A)BC/$r/r;  # $1

您可以使用/ee修饰符强制进行第二次插值,但替换部分在语法上必须是 Perl 代码,例如

my $s = 'ABC';
my $r = '"(" . $1 . ")"';
say $s =~ s/A(B)C/$r/ree;  # (B)

相关内容