[英]python: extracting variables from string templates
我熟悉使用模板將變量插入字符串的功能,如下所示:
Template('value is between $min and $max').substitute(min=5, max=10)
我現在想知道的是,是否可以反過來。 我想取一個字符串,並使用模板從中提取值,以便我有一些包含提取值的數據結構(最好只是命名變量,但dict很好)。 例如:
>>> string = 'value is between 5 and 10'
>>> d = Backwards_template('value is between $min and $max').extract(string)
>>> print d
{'min': '5', 'max':'10'}
這可能嗎?
這叫做正則表達式 :
import re
string = 'value is between 5 and 10'
m = re.match(r'value is between (.*) and (.*)', string)
print(m.group(1), m.group(2))
輸出:
5 10
更新1.名稱可以提供給組:
m = re.match(r'value is between (?P<min>.*) and (?P<max>.*)', string)
print(m.group('min'), m.group('max'))
但是這個功能並不經常使用,因為通常有一個更重要方面的問題:如何准確捕獲你想要的東西(這個特殊情況並不是什么大問題,但即使在這里:如果字符串value is between 1 and 2 and 3
怎么辦? value is between 1 and 2 and 3
- 應該接受字符串以及min
和max
多少?)。
更新2.有時更容易將正則表達式和“常規”代碼組合在一起,而不是制作精確的正則表達式:
m = re.match(r'value is between (?P<min>.*) and (?P<max>.*)', string)
try:
value_min = float(m.group('min'))
value_max = float(m.group('max'))
except (AttributeError, ValueError): # no match or failed conversion
value_min = None
value_max = None
當你的文本包含許多要處理的塊(如不同類型的引號中的短語)時,這種組合方法尤其值得記住:在棘手的情況下,定義單個正則表達式以處理塊的分隔符和內容比定義幾個更難諸如text.split()
類的步驟,可選的塊組合以及每個塊的獨立處理(使用正則表達式和其他方法)。
完全取消替換是不可能的。 例如,問題是某些字符串不明確
value is between 5 and 7 and 10
將有兩種可能的解決方案: min = "5", max = "7 and 10"
, min = "5 and 7", max = "10"
但是,您可以使用正則表達式獲得有用的結果:
import re
string = 'value is between 5 and 10'
template= 'value is between $min and $max'
pattern= re.escape(template)
pattern= re.sub(r'\\\$(\w+)', r'(?P<\1>.*)', pattern)
match= re.match(pattern, string)
print(match.groupdict()) # output: {'max': '10', 'min': '5'}
您可以使用difflib模塊比較兩個字符串並提取所需的信息。
https://docs.python.org/3.6/library/difflib.html
例如:
import difflib
def backwards_template(my_string, template):
my_lib = {}
entry = ''
value = ''
for s in difflib.ndiff(my_string, template):
if s[0]==' ':
if entry != '' and value != '':
my_lib[entry] = value
entry = ''
value = ''
elif s[0]=='-':
value += s[2]
elif s[0]=='+':
if s[2] != '$':
entry += s[2]
# check ending if non-empty
if entry != '' and value != '':
my_lib[entry] = value
return my_lib
my_string = 'value is between 5 and 10'
template = 'value is between $min and $max'
print(backwards_template(my_string, template))
給:{'min':'5','max':'10'}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.