用中文 API 讓正則表達式更易讀寫?

木蘭語言重現項目中用到了很多正則表達式,其中不乏不那麼一目瞭然的(Python實現):python

標識符:r'\$?[_a-zA-Z\u4e00-\u9fa5][_a-zA-Z0-9\u4e00-\u9fa5]*'  

雙引號字符串: r'(\")((?<!\\)\\\1|.)*?\1'

字符串插值相關:r'\\\(([^\\\)]*)\\\)|`([^`]*)`'

由此想到是否有 API 可以構建正則表達式。找到 PythonVerbalExpressions,它首頁上一個示例以下:git

verbal_expression.
start_of_line().
find('http').
maybe('s').
find('://').
maybe('www.').
anything_but(' ').
end_of_line()

對應正則: ^(http)(s)?(\:\/\/)(www\.)?([^\ ]*)$github

看起來的確比較可讀,並且若是改成中文 API 的話,命名會更簡短:正則表達式

開頭().
尋找('http').
或許('s').
尋找('://').
或許('www.').
除了(' ').
結尾()

問題是這個庫的功能彷佛有限,僅支持小部分正則語法,因而考慮改進。express

設想中的 API 示例

以開頭的木蘭實現中的幾個正則爲例,用設想中的 API 表達後進行對比code

標識符:字符串

至多一個("$").一個("_", 大小寫英文, 中文).任意個("_", 大小寫英文, 數字, 中文)

原始正則表達式對比:r'\$?[_a-zA-Z\u4e00-\u9fa5][_a-zA-Z0-9\u4e00-\u9fa5]*'

雙引號字符串:get

分組(雙引號)
  .最小匹配(
    任意個(
      分組(
        皆可(
          前面不是(反斜槓).一個(反斜槓).一個(引用分組(1)),
          一個(非換行字符))
      )
    )
  )
  .引用分組(1)

r'(\")((?<!\\)\\\1|.)*?\1'

字符串插值相關:it

皆可(
  一個(反斜槓).一個(左小括號).分組(任意個(不是(反斜槓, 右小括號))).一個(反斜槓).一個(右小括號),
  一個(反引號).分組(任意個(不是(反引號))).一個(反引號)
)

r'\\\(([^\\\)]*)\\\)|`([^`]*)`'

相對原始正則表達式,在可讀性以外還有幾個優點:io

  • 不需爲正則的特殊意義字符加反斜槓,如 \,(,) 等
  • 明確運算優先級,好比雙引號字符串中的 | 和 (?<!)...

在易寫方面,相對於正則的符號語法,API 語義更加直白。

歡迎意見建議。

相關文章
相關標籤/搜索