2011-12-06 129 views
1

我有一些字符和字符串列表的輸入字符串。我需要的是隻選擇符合包含字符的模式的字符串。 對於excample:正則表達式來檢查字符是否匹配字符串

輸入字符= 「問」 應該接受 「問」, 「SAK」, 「KAS」 ...... 但不應該接受 「AKK」, 「AAS」 ......

現在我用像 「^ [S | A | k]的[S | A | k]的[S | A | K] $」 的格局 但它probablem,它接受和重複字符( 「AKK」),因此,如果我使用這個我需要一些額外的檢查,如果preg_match的作品。

它使什麼比較複雜一點,可以有一些相同的字符: 輸入「askk」 應符合「akks」,而不是「kkks」或「assk」。

我相信這個檢查可以用單正則表達式來完成,但是我對正則表達式的知識不是那麼深。

(以獲取輸入和顯示resuls我使用PHP)

+6

這聽起來像是正則表達式不適合的東西。只需使用循環來計算每個字符在每個模式中出現的次數;它會更容易閱讀和更容易編寫。 –

回答

2

爲什麼在這裏使用正則表達式?我沒有看到好處。你可以做的是對輸入字符串進行排序(例如,'sak'和'ask'會變成'aks'),並將這個排序字符串與參考字符串'aks'進行比較。或者只是在引用字符串'ask'上使用相同的函數。類似這樣的:

function str_sort($str) { 
    $chars = str_split($str); 
    sort($chars); 
    return implode('', $chars); 
} 

$pattern = 'ask'; 
$input = 'sak'; 
$valid = str_sort($pattern) == str_sort($input); 

echo "Pattern: $pattern;\n"; 
echo "Input : $input\n"; 
echo "Valid : " . ($valid ? 'yes' : 'no') . "\n"; 
+0

regexp只是第一次嘗試,因爲它通常足夠強大。輸入可以包含「任何字符」之類的東西,但當然可以用其他方式完成,也許更優雅。就在過去,當我需要文本搜索正則表達式幫助。 – Dainius

+1

哦,我喜歡正則表達式,但在這種情況下,它並不是最優雅的解決方案。對於你想檢查的每一種模式,你都必須寫一個不平凡的正則表達式,這在我看來並不值得這麼麻煩。看看其他一些答案,看看我的意思。僅僅因爲這可能並不意味着它需要完成。但你已經明白了,看起來似乎:) – Bart

3

它實際上是相當困難的解決使用正則表達式之類的問題。你可以做到這一點,如果你有前瞻性表達。以下是一個示例,其中(?=...)是一個超前表達式。

/^(?=.*a)(?=.*s)(?=.*k).{3}$/ 

這裏(?=.*a)表達式的每個匹配的字母,在表達式的任何位置,和{3}指定,它必須是三個字符。

這變得複雜時,你有重複的字符,但它仍然是可能的。對於aask

/^(?=.*a.*a)(?=.*s)(?=.*k).{4}$/ 

當第一個僅如果在字符串中的任何2個a s比。

你可以做到這一點其他一些方式。例如,您可以遍歷每個字符並計算每個字母的數量,並將其存儲在一個數組中(即O(n)),或者可以按字母順序對字符進行排序(aks)並逐字符匹配字符串是O(無論你的排序算法是什麼))。

+0

感謝您的回答。我希望這種方式可以解決搜索問題,如果沒有,也許會需要重新考慮搜索算法。 – Dainius

1

這裏是「askk」的解決方案:

^(?=.*a)(?=.*s)(?=(?:.*k){2})[ask]{4}$ 

的想法是使用向前看符號,以確保在字符串中存在的第一個每個字符的正確的號碼,然後消耗串的保證休息只使用提供的集合中的字符。

See it working on Rubular.

+0

感謝您的回答和鏈接。 – Dainius

相關問題