我对正则表达式一般都很陌生,在准备参加秋季学期的Perl课程时,我想早点弄湿我的脚。我仍然围绕着他们,并做了非常基本的事情来了解匹配和替换是如何工作的。所以我写了一个简单的脚本来检查员工的身份证号码是否有效。我想出的简单要求是:
我不能为我的生活弄清楚如果它有多于零的情况如何使条件失败。我的代码如下所示:
$s;
print("Please enter your id number: ");
$s = <STDIN>;
if(($s =~ /^9/) && ($s =~ /0{1}/))
{
print("ID is valid\n");
}
else
{
print("ID not valid\n");
}
条件的第二部分($ s =〜/ 0 {1} /)我读作“只匹配一个零”但如果数字是包含多个零的东西,只要它们是无效的,它就不会起作用不重复(例如:90401返回有效,其中90091无效)。我知道这是可能的,但我已经尝试了很多没有解决方案的组合。正确方向的任何一点都是最有帮助的。
答案 0 :(得分:4)
最有效的代码是拒绝最有可能发生的坏情况(包含非数字)的代码,然后是快速进行perl检查的情况(从9开始)然后是最终情况(不超过1)零)。
if ($s =~ m/[^0-9]/ || $s =~ m/^[^9]/ || ($s =~ s/0/0/g) > 1) {
print "Invalid\n";
}
快速单个正则表达式,如果ID有效则为true,但它仍然比我对无效输入的第一个解决方案慢,并且在有效输入上没有更快:
m/^9[1-9]*(0[1-9]*)?$/
这与正则表达式一样快,因为我认为可以在一次操作中完成工作。使用?:非捕获组似乎会更快,它应该,但在实际的perl实现中,它会慢大约15%。
答案 1 :(得分:2)
这个正则表达式应该这样做:
/^9[1-9]*0?[1-9]*$/
以9开头,任意数字1-9,可能为0,后跟任意数字1-9。
答案 2 :(得分:1)
if ($s =~ /^9[1-9]*0?[1-9]*$/)
或者您可以使用@{[$n =~ /0/g]}
来计算“0”。
if (($s =~ /^9[0-9]+$/) && (@{[$s =~ /0/g]} <= 1))
答案 3 :(得分:1)
默认情况下,匹配运算符m //(或简称//)扫描字符串以查找与模式的第一个匹配项,然后退出。
我读的是“只匹配一个零”
它实际上是“正好匹配一次0”。
因此匹配运算符将扫描字符串“900009”,并在字符串中的位置1处找到一次0匹配,然后退出。匹配运算符也会找到匹配0正好2次,匹配0正好3次,并且匹配0正好4次在字符串中的位置1。
我不能为我的生活找出如果条件有多于零的情况如何使条件失败。&lt;
如何在字符串中找到0的所有匹配项,如果它超过1,那么拒绝该字符串?
use strict;
use warnings;
use 5.012;
my @strings = (
"90909",
"909",
"999",
);
for my $str (@strings) {
my @matches = $str =~ /0/g;
say scalar @matches;
}
--output:--
2
1
0
实际上有一种奇特的方法可以将计数排在一行:
my $count = () = $str =~ /0/g;
答案 4 :(得分:1)
在接受的答案中实际上有很多冗余。它不仅会计算所有零,还会花费不必要的时间来替换它们!?
以下没有那么多冗余,一旦找到两个零就会停止:
/^9[0-9]*\z/ && /^[^0]*+(?:0[^0]*+)?+\z/
or die;