【问题标题】:How do I split a string using a regular expression in Perl?如何在 Perl 中使用正则表达式拆分字符串?
【发布时间】:2017-02-28 21:44:13
【问题描述】:

我在 Perl 中有一个字符串:'CCCCCCCC^hC^iC^*C^"C^8A'

我想使用正则表达式分割这个字符串:"^[any_character]C"。换句话说,我想用实际字符^ 分割它,然后是任何字符,然后是一个特定的字母(在本例中为C,但它可以是A,或任何其他字符)。

我尝试查看其他问题/帖子,最后想出了我的@split_str = split(/\^(\.)C/, $letters),但这似乎不起作用。

我确定我做错了什么,但我不知道是什么。

【问题讨论】:

  • 试试/\^.C/s..
  • 作为后续,我试图找出最有效的方法来计算我的字符串的 ^.C (或任何字母)的数量。如果我的字符串大约有 1000 个字符长,拆分并从数组长度中减去 1 会更快,还是简单地计算字符串中正则表达式的数量会更快?
  • 所以在 python 中,我使用了相同的正则表达式,但它不起作用。我正在导入 re,并使用相同的字符串执行 re.findall("\^.C/", string),但它不起作用。它是 python 的不同正则表达式吗(我不认为是)。
  • 如果您有新问题,请将其作为新问题发布。

标签: regex string perl


【解决方案1】:

你们很亲密。您的代码中只有几个错误。在我解释它们之前,这是我用来测试解决方案的代码。

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use Data::Dumper;

$_ = 'CCCCCCCC^hC^iC^*C^"C^8A';

my @data = split /\^(\.)C/;

say Dumper @data;

用你原来的正则表达式运行它,我们得到这个输出:

$VAR1 = 'CCCCCCCC^hC^iC^*C^"C^8A';

根本没有发生分裂。那是因为您的正则表达式包含\.。点匹配字符串中的任何字符,但是通过使用反斜杠将其转义,您告诉 Perl 将其视为普通点。您的字符串中没有点,因此正则表达式不匹配且字符串未拆分。

如果我们删除反斜杠,我们会得到以下输出:

$VAR1 = 'CCCCCCCC';
$VAR2 = 'h';
$VAR3 = '';
$VAR4 = 'i';
$VAR5 = '';
$VAR6 = '*';
$VAR7 = '';
$VAR8 = '"';
$VAR9 = '^8A';

这样更好。发生了一些分裂。但是因为我们在圆点 ((.)) 周围有括号,所以 Perl 已经“捕获”了圆点匹配的字符并将它们添加到 split() 返回的值列表中。

如果我们删除这些括号,我们只会得到分割标记之间的值。

$VAR1 = 'CCCCCCCC';
$VAR2 = '';
$VAR3 = '';
$VAR4 = '';
$VAR5 = '^8A';

请注意,我们得到了一些空元素。那是因为在你的字符串中像“^hC^iC”这样的地方,两个相邻的分割标记之间没有数据。

通过在整个正则表达式 (split /(\^.C)/) 周围移动括号,我们可以获得一个列表,其中包括所有拆分标记以及它们之间的数据。

$VAR1 = 'CCCCCCCC';
$VAR2 = '^hC';
$VAR3 = '';
$VAR4 = '^iC';
$VAR5 = '';
$VAR6 = '^*C';
$VAR7 = '';
$VAR8 = '^"C';
$VAR9 = '^8A';

这些选项中的哪一个对您最有用取决于您正在尝试做什么。

【讨论】:

    【解决方案2】:

    当您说 [any_character] 时,您必须表示. 模式,点匹配任何字符但换行符,如果您使用s 修饰符,它将匹配任何字符。

    所以,在你的情况下,你不应该逃避点:

    @split_str = split /\^.C/, $letters;
                          ^
    

    或者,使用s 修饰符:

    @split_str = split /\^.C/s, $letters;
                             ^
    

    插入符号应转义以表示正则表达式模式中的文字插入符号。

    【讨论】:

      【解决方案3】:

      有一个关于计数而不是拆分的问题。 可以使用正则表达式替换和全局 s//g 进行计数和标量返回($_ 包含修改后的文本):

      my $text = 'CCCCCCCC^hC^iC^*C^"C^8C^9A^!B'; #litte longer than yours
      $_ = $text ;
      my $countanychar = s/\^.C//g ;
      print  "counting any char and C:\t $countanychar in $text\n";
      
      $_ = $text ;
      my $countnormalchar = s/\^\wC//g ; # h and i and 8  in this example avoid the * and "
      print  "counting normal char and C:\t $countnormalchar in $text\n";
      
      $_ = $text ;
      my $countnumber = s/\^\dC//g ;# the 8 in this example
      print  "counting number and C:\t $countnumber in $text\n";
      
      $_ = $text ;
      my $countextended = s/\^.\w//g ;# the he C and the A
      print  "counting extended C and A and B:\t $countextended in $text\n";
      

      【讨论】:

        【解决方案4】:

        像这样尝试@split_str = split(/\^/, $letters)

        【讨论】:

        • " 我想用实际字符 ^ 分割它,然后是任何字符,然后是一个特定的字母(在本例中是 C,但它可以是 A,或任何其他字符)。"你的回答没有做到这一点。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-15
        • 2011-12-28
        • 2017-02-23
        相关资源
        最近更新 更多