[英]Regex to match one character exactly one time anywhere inside a string
[英]Perl Regex: How to match exactly one of a character
我通常對正則表達式不熟悉,在准備秋季學期的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無效)。 我知道這已經成為可能,但是我已經嘗試了很多沒有解決方案的組合。 朝着正確方向的任何觀點都是最有幫助的。
最有效的代碼是拒絕最有可能發生的不良情況(包含非數字)的代碼,然后拒絕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%。
這個正則表達式應該這樣做:
/^9[1-9]*0?[1-9]*$/
以9開頭,任意數為1-9,可能為0,然后是任意數1-9。
if ($s =~ /^9[1-9]*0?[1-9]*$/)
或者,您可以使用@{[$n =~ /0/g]}
來計數“ 0”。
if (($s =~ /^9[0-9]+$/) && (@{[$s =~ /0/g]} <= 1))
默認情況下,匹配運算符m //(或簡稱//)掃描與模式的第一個匹配項的字符串,然后退出。
我的讀法是“僅匹配一個零”
它實際上顯示為“正好匹配0一次”。
因此,匹配運算符將掃描字符串“ 900009”,並在字符串中的位置1處恰好找到一次匹配0的匹配項,然后退出。 匹配運算符還將在字符串中的位置1處找到一個完全匹配0的匹配2次,一次完全匹配0個匹配的3次,以及完全匹配0個完全匹配的4次。
我一輩子都無法弄清楚如果條件超過一個零,如何使條件失敗。
如何找到字符串中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;
接受的答案中實際上有很多冗余之處。 而且它不僅計算所有零,而且花費不必要的時間替換它們!
以下內容沒有太多的冗余,一旦找到兩個零,它就會停止:
/^9[0-9]*\z/ && /^[^0]*+(?:0[^0]*+)?+\z/
or die;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.