在為正則運算式撰寫語法/決議器時,我想知道為什么以下結構在正則運算式語法中在語法和語意上都是有效的(至少據我所知)?
- 一個字符類的重復,例如:

- 零寬度斷言的重復,例如:

- 虛假立場的斷言,例如:

對我來說,這種型別的語法似乎允許使用SELECT SELECT SELECT SELECT SELECT col FROM tbl. 換句話說,為什么沒有將正則運算式語法定義為比實際更嚴格?
uj5u.com熱心網友回復:
首先,這不是一個很好的類比。SELECT據我所知,您使用多個關鍵字的陳述句不是 SQL 語法的一部分,因此它根本不合語法。字符類中的重復元素更像 SQL 構造:
SELECT * FROM table WHERE Value IN (1, 2, 3, 2, 3, 2, 3)
我認為大多數(如果不是全部)SQL 處理器都允許這樣做。您可能會爭辯說,如果發出警告訊息會很好,但是通常的 SQL 介面(查詢從客戶端發送到服務器并回傳結果)不會為警告留出空間。
當然,字符類中的重復字符通常表明正則運算式是由對字符類是什么只有模糊概念的新手撰寫的。如果你在 SO's 閑逛彈性詞法分析器足夠長的時間,你會看到學生寫正則運算式的頻率,比如[a-z|A-Z|0-9], 甚至[begin|end]. 如果 flex 在字符類中檢測到重復字符,這些錯誤將收到警告,這可能對學生編碼器有用,也可能沒有用。(閱讀和理解警告資訊顯然不是與生俱來的技能。)但需要問一下,像 Flex 這樣的工具的目標受眾是誰,我認為答案不是“不耐煩不閱讀檔案的初學者” ”。當然,非新手程式員也可能會犯這種錯誤,通常是由于拼寫錯誤,但這種錯誤并不常見,而且在除錯程序中很容易被發現。
如果您已經開始使用正則運算式決議器,那么您應該已經知道為什么這些規則通常不是正則運算式庫的功能。您放置在語法上的每條規則都必須是:
- 精確定義,
- 記錄在案,
- 實施的,
- 采取適當的行動(這可能意味著使界面復雜化以允許警告)。
- 所有這些都需要進行徹底的測驗。
為了防止在技術上甚至不是錯誤的事情發生,需要做很多作業。捕獲這些錯誤(如果它們是錯誤的話)可能會使正則運算式的“語法”對背景關系敏感。(換句話說,你不能撰寫一個背景關系無關的語法來禁止字符類中的重復。)
此外,實際上所有這些運算式都可能在野外出現,通常是在正則運算式是通程序式生成的情況下。例如,假設您有一組單詞,并且您想撰寫一個正則運算式,它將匹配不在任何單詞中的任何字符序列。簡單的解決方案是[^firstsecondthirdwordandtherest] 。當然,您可能會費心對單詞中的單個字母進行重復資料洗掉——在某些編程語言中這是一項簡單的任務,但在其他編程語言中會更復雜——但是否有必要?
關于您的其他兩個示例,重復和非終端$,有實際的正則運算式庫,其中那些以某種不同的方式解釋。許多較舊的正則運算式庫(包括 (f)lex)僅$在出現在正則運算式的末尾時才將其視為零長度的字串結尾斷言;此類別庫會將$除最后一個之外的所有 sa$$$$$$$$視為匹配文字$。其他人將$其視為行尾斷言,而不是字串結尾斷言。但我不知道有哪些將這些視為錯誤。
有一個很好的論點是,諸如regex101 之類的教學工具可能會對可疑的正則運算式發出警告,這一任務通常稱為“linting”。但是對于一個生產正則運算式庫,幾乎沒有什么收獲,而且有很多痛苦。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/512188.html
標籤:解析句法语法
