2014-04-30 101 views
3

基本上,我只是想知道如果存在這樣的功能:多少百分比的字符串相匹配的正則表達式

$string = 'helloWorld'; 

// 1 uppercase, 1 lower case, 1 number and at least 8 of length 
$regex = '/^\S*(?=\S{8,})(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[\d])\S*$/' 

$percent = matchPercent($string, $regex); 

echo "the string match {$percent}% of the given regex"; 

然後,其結果可能是這樣的:

字符串匹配75給定的正則表達式

看到另一篇文章和問題%,我可以做somehitng這樣的:

$uppercase = preg_match('@[A-Z]@', $password); 
$lowercase = preg_match('@[a-z]@', $password); 
$number = preg_match('@[0-9]@', $password); 

但是,我們的目標是,如果你想這樣做的正則表達式的方式,並根據您所提供的用例在功能

+0

它不太可能存在 - 正則表達式有能力如此複雜(前瞻/後面和嵌套捕獲子模式),無論如何可能很難計算百分比匹配。 – halfer

+2

不是答案,但也許是一個出發點:http://www.php.net/manual/en/function.similar-text.php – TecBrat

+0

IdoNotNeedCodeAsHomeWork()|| justAnPossibility() – manix

回答

5

與任何正則表達式的工作,我們需要使整個正則表達式可選。我們也將在我們的預見中使用捕獲組。第一

但第一件事情,讓我們來改善你的正則表達式:

  • [\d]是多餘的,只要使用\d
  • \S*(?=\S{8,})刪除\S*部分,我們已經在最後。

我們的正則表達式看起來像^(?=\S{8,})(?=\S*[a-z])(?=\S*[A-Z])(?=\S*\d)\S*$

現在是棘手的部分,我們將添加組在我們向前看符號,使他們可選:

^(?=(\S{8,})?)(?=(\S*[a-z])?)(?=(\S*[A-Z])?)(?=(\S*\d)?)\S*$

你可能會問,爲什麼?這些組織是爲了讓我們可以在以後追蹤它們。我們使它們成爲可選項,以便我們的正則表達式始終匹配。這樣,我們可以做一些數學!

$regex = '~^(?=(\S{8,})?)(?=(\S*[a-z])?)(?=(\S*[A-Z])?)(?=(\S*\d)?)\S*$~'; 
$input = 'helloWorld'; 

preg_match_all($regex, $input, $m); 

array_shift($m); // Get rid of group 0 

for($i = 0, $j = $k = count($m); $i < $j; $i++){ // Looping 
    if(empty($m[$i][0])){ // If there was no match for that particular group 
     $k--; 
    } 
} 

$percentage = round(($k/$j) * 100); 
echo $percentage; 

Online php demo

+2

令人敬畏的演示文稿!我剛剛開始研究一些非常相似的東西,並且你打敗了我。 :D +1 –

+1

呃......我不知道該說什麼哈哈。非常感謝! – manix

+2

阿加...稍有不同,但你打敗了我。 :)你是男人。 – zx81

2

編輯:我看到了哈姆扎幾乎同樣的想法。

當然!這是一個非常有趣的問題。

這是一個簡化的驗證正則表達式的解決方案。

$str = 'helloword'; 
$regex = '~^(?=(\S{8,}))?(?=(\S*[a-z]))?(?=(\S*[A-Z]))?(?=(\S*[\d]))?.*$~'; 

if(preg_match($regex,$str,$m)) { 
    $totaltests = 4; 
    $passedtests = count(array_filter($m)) -1 ; 
    echo $passedtests/$totaltests; 
} 

輸出:0.5

它是如何工作的?

  1. 對於每個條件(以前瞻表示),我們捕捉到可以匹配的文本。
  2. 我們定義$totaltests作爲檢驗的總次數
  3. 我們指望與count(array_filter($m)) -1其去除空組和組0,即,整體匹配通過測試的次數。
  4. 分割。
+0

我真的很驚訝:我不知道PHP支持可選的lookahead。 [regex101.com](http://regex101.com/r/bS5vG0)抱怨它無法量化。 – HamZa

+1

@Hamza regex101抱怨了很多事情......我昨天給出了一個解決方案,聽起來好像這個人認爲這是錯誤的,因爲它在regex101中不起作用,即使它在本地代碼中執行。 :) – zx81

+0

@hamza但無論如何,爲了實踐的目的,我敢肯定你同意,不管我們是使可選擇的前瞻還是測試被評估,都沒有什麼區別......也許你沒有兩個''''''' – zx81

相關問題