识别字符串中的符号

时间:2016-06-27 22:14:12

标签: python tokenize

我正在实施一个简单的DSL。我有以下输入字符串:

std::vector<int> a;
..
a.resize(t);
..
cin >> a[i]

我有以下数据:

txt = 'Hi, my name is <<name>>. I was born in <<city>>.'

我需要实现以下功能:

{ 
  'name': 'John',
  'city': 'Paris',
  'more': 'xxx',
  'data': 'yyy',
  ...
}

我得到的地方:

def tokenize(txt):
    ...
    return fmt, vars

也就是说,fmt = 'Hi, my name is {name}. I was born in {city}.' vars = ['name', 'city'] 可以传递给str.format()函数,而fmt是检测到的标记的列表(这样我就可以在数据中执行查找,这可以是比我描述的更复杂,因为它可以分成几个名称空间)

在此之后,处理格式很简单:

vars

def expand(fmt, vars, data): params = get_params(vars, data) return fmt.format(params) 正在执行简单的数据查找,并返回类似的内容:

get_params

我的问题是:

如何实现tokenize?如果知道delitimers是params = { 'name': 'John', 'city': 'Paris', } <<,我怎样才能检测到令牌?我应该去正规用途,还是有更容易的路径?

这类似于>>,甚至pystache本身正在做的事情,但我想要一个轻量级的实现。在这个阶段,稳健性并不是​​非常关键。

2 个答案:

答案 0 :(得分:2)

是的,这是regexp的完美目标。找到开始/结束引号,用大括号替换它们,并将符号名称提取到列表中。您对法律符号有完整的描述吗?您需要进行搜索,例如

/\<\<([a-zA-Z]+[a-zA-Z0-9_]*)\>\>/

对于经典变量名称(请注意,这不包括前导下划线)。你是否熟悉regexp从这里接受它?

答案 1 :(得分:1)

import re

def tokenize(text):
    found_variables = []
    def replace_and_capture(match):
        found_variables.append(match.group(1))
        return "{{{}}}".format(match.group(1))
    return re.sub(r'<<([^>]+)>>', replace_and_capture, text), found_variables

fmt, vars = tokenize('Hi, my name is <<name>>. I was born in <<city>>.')
print(fmt)
print(vars)

# Output:
# Hi, my name is {name}. I was born in {city}.
# ['name', 'city']