我想用REGEX驗證PHP中的輸入。我想檢查輸入中是否有%s
字符組,並且它只出現一次。否則,該規則應該失敗。正則表達式/ PHP檢查字符組是否只出現一次
這是我已經試過:
preg_match('|^[0-9a-zA-Z_-\s:;,\.\?!\(\)\p{L}(%s){1}]*$|u', $value);
(也有除此之外其他一些規則,我已經試過了(%s){1}
的一部分,它不工作)。
我相信這是一個非常簡單的解決方案,但我沒有真正進入REGEX的...謝謝你的幫助!
我想用REGEX驗證PHP中的輸入。我想檢查輸入中是否有%s
字符組,並且它只出現一次。否則,該規則應該失敗。正則表達式/ PHP檢查字符組是否只出現一次
這是我已經試過:
preg_match('|^[0-9a-zA-Z_-\s:;,\.\?!\(\)\p{L}(%s){1}]*$|u', $value);
(也有除此之外其他一些規則,我已經試過了(%s){1}
的一部分,它不工作)。
我相信這是一個非常簡單的解決方案,但我沒有真正進入REGEX的...謝謝你的幫助!
如果我理解你的問題,你需要一個積極的前瞻。向前看將導致表達式僅在找到單個%s時才匹配。
preg_match('|^(?=[^%s].*?[%s][^%s]*$)[0-9a-zA-Z_-\s:;,\.\?!\(\)\p{L}(%s){1}]*$|u', $value);
我將解釋每一部分如何工作
^(?=[^%s].*?[%s][^%s]*$)
是一個零寬度斷言 - (?=regex)
積極前瞻 - (這意味着它必須匹配,但不「吃」的任何字符)。這意味着整條生產線只能有1 %s
。
[0-9a-zA-Z_-\s:;,\.\?!\(\)\p{L}(%s){1}]*$
正則表達式的其餘部分也查看整個字符串,並確保整個字符串只包含字符類中的字符(如原始正則表達式)。
或者,您可以使用preg_match_all
與您的模式,並檢查匹配的數量。如果它是1,那麼你沒事 - 像這樣:
$result = (preg_match_all('|^[0-9a-zA-Z_-\s:;,\.\?!\(\)\p{L}(%s){1}]*$|u', $value) == 1)
試試這個:
'|^(?=(?:(?!%s).)*%s(?:(?!%s).)*$)[0-9_\s:;,.?!()\p{L}-]+$|u'
方括號內的(%s){1}
序列可能不會做你認爲是這樣,不過沒關係,解決的辦法是比較複雜的。實際上,{1}
絕不應該出現在正則表達式的任何地方。它並不能確保只有一件東西,正如許多人所假設的那樣。事實上,它不會做什麼;這是純粹的混亂。
EDIT(在回答評論):爲了確保只有特定序列的一個存在於一個字符串,你必須積極地檢查每一個單個字符,它歸類爲任一部分-OF- %s
或不是部分-。爲此,(?:(?!%s).)*
一次只消耗一個字符,之後負向超前已確認該字符不是%s
的開始。
當前瞻表達式的那部分退出匹配時,字符串中的下一個事物必須是%s
。然後第二個(?:(?!%s).)*$
開始進行確認,直到字符串結束爲止,不再有%s
序列。
不要忘記,前瞻表達式必須在兩端都錨定爲。因爲lookahead是主正則表達式啓動後的第一個主播,所以您不需要再添加其他^
。但前瞻必須以自己的$
結尾。
我設法用PHP的substr_count()功能來做到這一點,以下Johnsyweb建議使用替代的方式來進行驗證和因爲正則表達式的建議似乎相當複雜。
再次感謝您!
這比我的回答好得多!我不是一名PHP開發人員,因爲它被標記爲[正則表達式],所以我偶然發現了這個問題。 – Johnsyweb
鑑於你自己的答案,我建議這個問題的標題是不正確的。 – Johnsyweb
更改標題以反映我的答案。 – linkyndy