?模式?运算符不适用于在Perl中匹配一次

时间:2017-04-19 15:39:51

标签: perl

我是Perl的新手,正在练习一些程序。我遇到了语法错误。请帮帮我。

我的Perl程序

#!/usr/bin/perl

@list = qw/ food foosball subeo footnote terfoot canic footbridge /;

foreach ( @list ) {
    $first = $1 if ?(foo.*)?;
    $last  = $1 if /(foo.*)/;
}

print "First: $first, Last: $last\n";

输出

syntax error at MatchingOnlyOnce.pl line 9, near "if ?"
Execution of MatchingOnlyOnce.pl aborted due to compilation errors.

perl -v

的输出
This is perl 5, version 24, subversion 1 (v5.24.1) built for MSWin32-x64-multi-t
hread

Copyright 1987-2017, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

3 个答案:

答案 0 :(得分:8)

使用

public static void main(String[] args) throws IOException{
    Scanner in = new Scanner(System.in);

    int output = 0;
    int ip1_cols = 0;
    ip1_cols = Integer.parseInt(in.nextLine().trim());

    in.useDelimiter(" ");
    char[] ip1 = new char[ip1_cols];
    for(int ip1_j=0; ip1_j<ip1_cols; ip1_j++) {
        ip1[ip1_j] = in.next().charAt(0);

    }
    enumerate(ip1);
    for (Iterator iterator = possibleAleternatives.iterator(); iterator.hasNext();) {
        String cs = (String) iterator.next();
        System.out.println(cs);
    }

}
static Set<String> possibleAleternatives=new HashSet();

static void enumerate(char[] charArr){

    for (int i = 0; i < charArr.length; i++) {
        char c = charArr[i];

        if(c=='?'){
            findPossibleAlternatives(charArr, i);
        }
    }
    String s=String.valueOf(charArr);
    if(!s.contains("?")){
    possibleAleternatives.add(s);
    }
}

static void findPossibleAlternatives(char[] charArray,int i ){
    char[] newArr1=Arrays.copyOf(charArray, charArray.length);
    char[] newArr=Arrays.copyOf(newArr1, newArr1.length);
    newArr1[i]='0';
    enumerate(newArr1);
    newArr1=null;
    newArr[i]='1';
    enumerate(newArr);
    newArr=null;
}

$first=$1 if m?(foo.*)?; 可以用作?PATTERN?的快捷方式,但是当您使用m?PATTERN?作为分隔符时,您不能再省略匹配运算符的前导m

5.14弃用了忽略?中的前导m的功能。

5.22删除了忽略m?PATTERN?flags中的前导m的功能。

5.22和5.24的perlop列出m?PATTERN?flagsm?PATTERN?flags,但只有前者在这些版本中合法。

5.26的文档将不包含?PATTERN?flags的所有提及(与?PATTERN?相对)。

答案 1 :(得分:7)

如果您没有使用默认的/模式分隔符,则必须指定匹配操作,如$x =~ m{...}$x =~ m!...!等。

?...?与其他替代分隔符不同,因为?...?执行的内容与/.../不同。 perldoc perlreref目前声明:

  

?pattern?m/pattern/类似,但只匹配一次。不能使用备用分隔符。必须使用reset()重置。

这是misleading,因为Perl 习惯于识别普通?...?,但几年前支持was completely removed

  

[perl#120912] [PATCH]删除对“PATTERN”的支持?没有明确的&#39; m&#39;操作

     

...

     

自Perl v5.14(提交以来)发出了弃用警告   725a61d70),并排除使用?作为一元算子之后的算子   默认为$ _,例如:

ref ? $_ : [$_]

以下是弃用和最终删除的动机:

  

弃用?PATTERN?,建议使用等效的m?PATTERN?语法   为了最终允许在新的运营商中使用问号   这目前是模棱两可的。

如果您刚开始学习Perl,则应启用strictwarnings。在最小的适用范围内声明您的变量。

#!/usr/bin/env perl

use strict;
use warnings;

my @list = qw/food foosball subeo footnote terfoot canic footbridge/;
my ($first, $last);

foreach my $item (@list) {
    $item =~ m?(foo.*)?
        and $first = $1;
    $item =~ /(foo.*)/
        and $last = $1;
}
print "First: $first, Last: $last\n";

输出:

$ perl tt.pl
First: food, Last: footbridge

答案 2 :(得分:0)

很多关于Perl的东西对于编程语言来说都是不寻常的,而且你发生在很少使用的语言的一角

Perl由语言学家Larry Wall设计,Perl和口语之间有许多相似之处。 Perl允许某些构造的缩写,例如,像

这样的模式匹配
/abc/

相当于

$_ =~ m/abc/

也就是说,如果看起来像一个正则表达式模式,它将被视为一个,无论前导m是否存在。此外,默认情况下,许多Perl操作符在$_上工作,这允许您编写几行代码而无需明确提及变量

但是m?...?是一个老式的结构,它实际上被词法变量所取代。如果使用my声明变量,则不需要一次性匹配或相应的reset运算符。这是您声明变量

的生命周期的声明

如果您刚开始使用Perl,我建议您

  • 始终 使用use strictuse warnings 'all'启动每个计划。这不是可选的,因为它是防止简单错误和错误的第一道防线

  • 始终 使用my声明每个变量尽可能接近第一次使用。有时您可能希望在循环之前声明变量,以便在迭代期间保持其值,但通常变量应该是临时的,仅对几行代码有用

  • 忘掉m?...?。我从未见过在专业编写Perl的二十年中使用它的程序

我希望这会有所帮助