我從用戶那里得到了一個輸入串列,這些輸入是假定有效的 perl regexp 值。示例可能是:
\b[Bb]anana\b\s*Apples[BANANA]\s
有沒有安全的方法來驗證這些字串?
uj5u.com熱心網友回復:
首先,考慮您希望讓用戶對模式執行多少操作。Perl 正則運算式可以運行任意代碼。
但是,要驗證您可以將字串用作模式而不會導致致命錯誤,您可以使用qr//運算子來編譯字串并回傳正則運算式。如果有問題,它qr會給你一個你可以捕捉到的致命錯誤eval:
my $pattern = eval { qr/$input/ };
如果您回傳undef,則該模式無效。而且,盡管問題中有評論,但制作無效模式的方法有無數種。我知道是因為我一直手動輸入它們,而且我還沒有辦法搞砸:)
這不會將模式應用于字串,但您可以使用它$pattern來進行匹配:
if( $pattern ) {
$target =~ $pattern; # or $target =~ m/$pattern/
}
uj5u.com熱心網友回復:
好吧,驗證正則運算式需要了解您期望的輸入型別。正則運算式運算子與自動機接受的字串集之間存在直接關系。
這里的問題是通常這組字串并不為人所知或指定不當,例如:
regex 中的基本運算子集是基本語言字符集(它提供要操作的符號)和使事情變得復雜的運算子:這是替代|(選擇一個或另一個),連接(沒有符號) ,因為兩個正則運算式只是放在一起表示來自一組的一組字串,然后是一個字串,這次來自第二組)和閉包,由 a 符號化* (這最后一個含義允許任何重復---包括none---來自上一組的字串)。
絕對所有的正則運算式都可以作為(主要是更復雜的)運算式來處理,它只使用這三個運算子,僅此而已。例如, 操作員可以通過重復它被施加到正則運算式,以及將被處理*的第二實體(由括號包圍到組它全部)的?可選后綴可由follwing規則進行處理(regexp)? == (regexp|) (利用它的替代或不是)
- 這
|意味著另一種選擇……您提供兩組字串,結果集是兩組的并集。這意味著如果一個字串屬于一個或任何一個集合,它就會被接受。 - 串聯意味著該集合是通過評估兩個集合的笛卡爾積來構建的。您需要制作成對的弦,從第一組中取出一個,從另一組中取出第二個,所有可能的組都以這種方式形成。
- 閉包意味著將字串構建為來自同一集合的(可能為零)實體的序列......這意味著您可以連接集合中的任何實體。
這組規則將為您提供構成正則運算式的完整字串集。這可能符合(或不符合)您的想法……但是如果您的想法定義不明確,那么它將成為您的正則運算式。
因此,作為一個結論,您需要一個通用程式來測驗您自己的想法以及您如何設計您的正則運算式。有一個定理(稱為抽水定理)用于演示正則運算式和有限狀態自動機的等價性。這是一項非常重要的成就,因為它允許您使用正則運算式進行高效的單次傳遞、字串識別。如果你深入研究,你會發現可以撰寫一個工具,從正則運算式可以系統地構建將被某些正則運算式接受的完整字串集。但這有一個問題,其中許多正則運算式創建了無限組的字串,這意味著演算法不會在有限的時間內完成。
作為最后的評論,我可以告訴您,這使正則運算式成為選擇字串的非常強大的工具。例如,您可以使用正則運算式來檢測復雜的事情,例如作為一串數字組成 23 的倍數的十進制形式,或者驗證信用卡號碼是否存在轉錄錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/354305.html
上一篇:匹配組后跟不同結尾的組
