簡體   English   中英

Perl正則表達式:如何完全匹配一個字符

[英]Perl Regex: How to match exactly one of a character

我通常對正則表達式不熟悉,在准備秋季學期的Perl課程時,我想早點弄濕自己。 我仍會全神貫注於它們,並做一些非常基本的事情來了解匹配和替換的工作原理。 因此,我編寫了一個簡單的腳本,用於檢查員工的身份證號碼是否有效。 我提出的簡單要求是:

  1. 必須從9開始
  2. 整數中只能有一個零

我無法終生想出如果條件大於零則如何使條件失敗。 我的代碼如下所示:

$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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM