Perl 字符串操作和查找

Perl string manipulation and find

我目前正在为 class 开发一个 phone 图书程序,我在使用正则表达式部分时遇到了一些问题,以便格式化我的文本并找到我要查找的内容.首先,我无法将 phone 数字文本编辑为我想要的内容。我能够找到连续 7 个数字 (777777) 的文本,但我无法将其替换为 (1-701-777-777)。

if($splitIndex[1] =~ m/^(\d{3}\d{4})/) {
      $splitIndex[1] =~ s/([\d{3}][\d{4}])/1-701-[]-[]/;
      print "Updated: $splitIndex[1]";
    }

当我 运行 这段代码的输出最终是(不会让我在这里嵌入图像是输出 https://imgur.com/a/8HtW7xm)。

其次,我在执行搜索的实际正则表达式部分时遇到了问题。我将所有可能的字母组合保存在 $letofSearch 中,将数字顺序组合保存在 $numOfSearch 中。通过在正则表达式中玩耍,我想出了如果我这样做 [$numOfSearch]+[$numOfSearch[-1]...[$numOfSearch[1] 它给了我正确的数字查找但我无法正确编写它在我的代码中。

    #If user input is only numbers
    if($searchValue =~ m/(\D)/) {
      #print "Not a number\n";
      if($splitIndex[1] =~ m/([$numOfSearch]+)/) {
        if($found == 0) {
            print "$splitIndex[0]:$splitIndex[1]\n";
            $found = 1;
        }
      }
      if($splitIndex[0] =~ m/([$letOfSearch])/i) {
        if($found == 0) {
            print "$splitIndex[0]:$splitIndex[1]\n";
            $found = 1;
        }
      }
      $found = 0;
    } else {
      #If it is a number search for that number combo immedietly
      if($splitIndex[1] =~ m/([$numOfSearch]+)/) {
        if($found == 0) {
            print "$splitIndex[0]:$splitIndex[1]\n";
            $found = 1;
        }
      }
      if($splitIndex[0] =~ m/([$letOfSearch])/i) {
        if($found == 0) {
            print "$splitIndex[0]:$splitIndex[1]\n";
            $found = 1;
        }
      }
      $found = 0;
    }
  }
}

而不是:

if($splitIndex[1] =~ m/^(\d{3}\d{4})/) {
      $splitIndex[1] =~ s/([\d{3}][\d{4}])/1-701-[]-[]/;
      print "Updated: $splitIndex[1]";
    }

试试这个:

if ($splitIndex[1] =~ s/(\d{3})(\d{4})/1-701--/)
{
    print "Updated: $splitIndex[1]";
}

在正则表达式中,一组方括号([])将匹配 一个且仅一个 字符,无论方括号之间是什么括号。因此,当您编写 [\d{3}][\d{4}] 时,它将匹配 恰好两个字符 ,因为您正在使用 两个 []。这两个字符将是 \d(任意数字)、{34} 之一,因为这是您在括号。

正则表达式方括号内的顺序无关紧要,因此 [\d{3}][}1527349806{3] 相同。如您所见,这可能不是您想要的。

你想做的是 捕获 \d{3}\d{4} 字符串,你用一组常规的 来做到这一点捕获 括号,像这样:(\d{3})(\d{4})

因为你只有一组括号(也就是说,你有 ([\d{3}][\d{4}]))并且它恰好包含两个 [],所以它恰好将两个字符放入 $1,而什么都没有变成 2 美元。这就是为什么当您尝试在 s/// 的后半部分使用 $2 时,它会抱怨 $2 中有未初始化的值。您试图使用一个根本没有设置的值 ($2)。

(此外,您进行了两组匹配:一组用于 m//,另一组用于 s///。我只是删除了 m// 匹配并保留了 s/// 匹配,使用它的 return 值来确定我们是否需要打印()任何东西。)

s///的第二部分不使用正则表达式,所以任何[]{}(,或 ) 将按字面意思显示为该字符。因此,如果您不想在最后的 phone 数字中使用方括号,请不要使用它们。这就是为什么我使用 s/.../1-701--/; 而不是 s/.../1-701-[]-[]/;.

所以当你写 s/([\d{3}][\d{4}])/1-701-[]-[]/ 时,([\d{3}][\d{4}]) 部分是将两个字符放入 $1,而没有放入 $2。这就是为什么你得到的结果包含 [77](用括号括起来的 $1)和 [](用括号括起来的 $2(未初始化的值))。

至于你的 post 的第二部分,我注意到你在正则表达式中使用了很多捕获括号,但你从未真正使用你捕获的内容。也就是说,您从不使用 $1(或 $2)。比如你写:

if($searchValue =~ m/(\D)/) {

其中有 m/(\D)/,但您永远不会在该代码的任何地方使用 $1。我想知道:如果您不在代码中的任何地方使用它,捕获该非数字字符有什么意义?

我见过程序员搞混了圆括号和方括号的用途。使用正则表达式时,方括号([]匹配(不捕获)恰好一个字符。他们匹配的是 not put in $1, $2, or any other $n.

另一方面,

圆括号 捕获 匹配的任何内容,方法是将 $1(或 $2、$3 等)设置为匹配的内容。通常,除非您计划稍后捕获并使用该匹配项,否则不应使用括号。 (此规则的主要例外是如果您需要对一组匹配项进行分组,如下所示:m/I have a (cat|dog|bird)/。)

许多程序员混淆了正则表达式中的方括号和圆括号,并试图将它们互换使用。他们会写类似 m/I have a [cat|dog|bird]/ 的东西,却没有意识到它与 m/I have a [abcdgiort|]/ 相同(它没有捕获任何内容,因为没有括号),并且想知道为什么他们的程序会抱怨 $1 是未初始化的值。

这是一个常见的错误,所以如果您不知道其中的区别,请不要难过。现在你知道了,希望你能找出代码第二部分需要更正的地方。

希望对您有所帮助。