2016-11-08 51 views
3

看看下面的PHP正則表達式計數總的話:PHP - 在正則表達式模式

/^(what is|tell me) your name$/

我要確定模式中可用的單詞總數。正確的答案應該是4看到的以下組合兼容:

what is your name => 4 words 
tell me your name => 4 words 

簡單count(explode(' ', '/^(what is|tell me) your name$/'))是不會削減它,看到的explode函數將返回以下:

['/^(what', 'is|tell', 'me)', 'your', 'name$/']

...定義了5個「單詞」,實際上只有4個單詞在模式中可用。

再舉一例:

/^(my|the) name is (\w+)$/ => 4 words

是否有一個功能已經可用,我可以利用,否則我將不得不從頭開始創建一個相當高科技嗎?

榮譽如果有人願意給它一個鏡頭。

+3

使用'sizeof(explode(「」,$ str))' – Mohammad

+2

不正確。這會將第一種模式分成:['/ ^(what','is | tell','me]','your','name $ /'] - 這是5個單詞。 – Luka

+0

我認爲沒有魔術功能可以告訴你書寫模式可以匹配多少個單詞。可能你需要寫自己的。什麼[關於嵌套括號?](https://www.regex101.com/r/NtHf6I/1) –

回答

1

這是非常難看,但也許你可以使用一些邏輯?它接縫工作。

我基本上將字符串分成2個不同的字符串。 $first_string是圓括號()之間的部分。 我將這個字符串分解爲|並計算新字符串+1中的空格。

字符串的第二部分$second_string我簡單地刪除所有非字母字符和雙空格並計算單詞。

最後我添加$first_string + $second_string以獲得最終結果。

這樣做的一個弱點是,如果你有一個字符串(something | something else),我不認爲我的計算空格的方法可以在|的每個站點上處理不同數量的單詞。

<?php 

    $string='/^(my|the) name is (\w+)$/'; 
    $pattern='/\(([^\)]+)\)/'; // Get text between() 
    $pattern2 = '([^a-zA-Z0-9 $])'; // all non alphabetic chars except $ 

    preg_match($pattern,$string, $first_string); // get text 
    $first_string=explode('|', $first_string[0]); 

    $new_string = preg_replace($pattern, '', $string); 
    $new_string2 = preg_replace($pattern2, '', $new_string); 
    $new_string2 = removeWhiteSpace($new_string2); 

    // count words 
    $first_string=substr_count($first_string[0]," ")+1; 
    $second_string = sizeof(explode(" ", $new_string2)); // count words 

    // removes double white space 
    function removeWhiteSpace($text) 
    { 
     $text = preg_replace('/[\t\n\r\0\x0B]/', '', $text); 
     $text = preg_replace('/([\s])\1+/', ' ', $text); 
     $text = trim($text); 
     return $text; 
    } 

    echo $first_string+$second_string; // final result 


?> 
1

決定給自己一個去吧,這個概念有很多問題。這裏有一對夫婦:

/^(tell me|hey what is) your name$/

一個正確的答案將是既45字 - 呈現不一致。

/^hey what (.+) up to$/

在這種情況下會發生什麼?括號中可以包含任何數量的潛在單詞。

所以,一切的一切,函數的思想,以檢測一個明確的答案,或許,非常愚蠢的^ O^

不過,我給它一個鏡頭和這裏就是我想出了,不兼容(.+)和公平未經測試,釋放出恐怖...

/** 
* Try to detect min/max amount of words in the given pattern. 
* 
* @param string $pattern 
* @param string $or_words_pattern 
* @param string $unwanted_pattern 
* @return array 
*/ 
function regex_word_count(
    $pattern, 
    $or_words_pattern = '/\((\w|\s|\|)+\)/', 
    $unwanted_pattern = '/[^a-zA-Z0-9\|\(\)\s]/') 
{ 
    $result = ['min' => 0, 'max' => 0]; 
    $pattern = str_replace('\s', ' ', $pattern); 
    $pattern = preg_replace($unwanted_pattern, null, $pattern); 

    if (preg_match_all($or_words_pattern, $pattern, $ors)) { 
     $matches = current($ors); 

     foreach ($matches as $match) { 
      $strings = explode('|', $match); 

      foreach ($strings as $string) { 
       $counts[$match][] = count(explode(' ', $string)); 
      } 
     } 

     foreach ($counts as $count) { 
      $result['min'] += min($count); 
      $result['max'] += max($count); 
     } 

     $pattern = trim(preg_replace($or_words_pattern, null, $pattern)); 
     $pattern = preg_replace('/\s+/', ' ', $pattern); 
    } 

    if (!empty($pattern)) { 
     $count = count(explode(' ', $pattern)); 
     $result['min'] += $count; 
     $result['max'] += $count; 
    } 

    return $result; 
} 

例子:

$x = regex_word_count('/^(a{3}) ([abc]) (what is the|tell me) your (name|alias dude)$/'); 

die(var_dump($x)); 

// array(2) { 
// 'min' => 
// int(6) 
// 'max' => 
// int(8) 
// } 

這是一個有趣的練習中試圖做一些事情,那麼,IMPO ssible。