簡體   English   中英

Python 從 yaml 配置文件解釋正則表達式

[英]Python interpreting a Regex from a yaml config file

所以我有一個 yaml 文件,用作配置文件。 我正在嘗試使用正則表達式進行一些字符串匹配,但是我無法將正則表達式從 yaml 解釋為 python。 有問題的正則表達式如下所示:

regex:
    - [A-Za-z0-9]

當我嘗試使用re.match函數時,出現此錯誤:

Traceback (most recent call last):
  File "./dirpylint.py", line 132, in <module>
    sys.exit(main())
  File "./dirpylint.py", line 32, in main
    LevelScan(level)
  File "./dirpylint.py", line 50, in LevelScan
    regex_match(level)
  File "./dirpylint.py", line 65, in regex_match
    if re.match(expression, item) == None:
  File "/usr/lib/python2.7/re.py", line 137, in match
    return _compile(pattern, flags).match(string)
  File "/usr/lib/python2.7/re.py", line 229, in _compile
    p = _cache.get(cachekey)
TypeError: unhashable type: 'list'

我知道它將正則表達式解釋為列表,但是我將如何使用 yaml 文件中定義的正則表達式來搜索字符串?

我在我的 YAML 解析“引擎”中做到了這一點。

In [1]: from StringIO import StringIO
In [2]: import re, yaml
In [3]: yaml.add_constructor('!regexp', lambda l, n: re.compile(l.construct_scalar(n)))
In [4]: yaml.load(StringIO("pattern: !regexp '^(Yes|No)$'"))
Out[4]: {'pattern': re.compile(ur'^(Yes|No)$')}

如果您想使用 safe_load 和 !!python/regexp(類似於 ruby​​ 和 nodejs 的實現),這也有效:

In [5]: yaml.SafeLoader.add_constructor(u'tag:yaml.org,2002:python/regexp', lambda l, n: re.compile(l.construct_scalar(n)))
In [6]: yaml.safe_load(StringIO("pattern: !!python/regexp '^(Yes|No)$'"))
Out[6]: {'pattern': re.compile(ur'^(Yes|No)$')}

問題是 YAML,而不是 Python。
如果要在 YAML 文件中存儲包含文字方括號的字符串值,則必須引用它:

regex:
  - '[A-Za-z0-9]'

使用“單引號”意味着 YAML 不會解釋正則表達式中的任何反斜杠轉義序列。 例如\\b

另請注意,在此 YAML 中, regex的值是一個包含一個字符串的列表,而不是一個簡單的字符串。

您在YAML文件中使用了兩個列表結構。 加載YAML文件時:

>>> d = yaml.load(open('config.yaml'))

你得到這個:

>>> d
{'regex': [['A-Za-z0-9']]}

請注意,正則表達式中的方括號實際上正在消失,因為它們被識別為列表分隔符。 你可以引用它們:

正則表達式:-“[A-Za-z0-9]”

要得到這個:

>>> yaml.load(open('config.yaml'))
{'regex': ['[A-Za-z0-9]']}

所以正則表達式是d['regex'][0] 但是您也可以在yaml文件中執行此操作:

regex: "[A-Za-z0-9]"

這讓你:

>>> d = yaml.load(open('config.yaml'))
>>> d
{'regex': '[A-Za-z0-9]'}

因此,可以使用類似的字典查找來檢索正則表達式:

>>> d['regex']
'[A-Za-z0-9]'

...這可以說要簡單得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM