在python中反转字符串格式

时间:2018-01-31 07:00:15

标签: python regex string format

在python中,我们可以使用str.format来构造这样的字符串:

string_format + value_of_keys = formatted_string 

例如:

FMT = '{name:} {age:} {gender}'                   # string_format
VoK = {'name':'Alice', 'age':10, 'gender':'F'}    # value_of_keys
FoS = FMT.format(**VoK)                           # formatted_string

在这种情况下,formatted_string = 'Alice 10 F'

我只是想知道是否有办法从value_of_keysformatted_string获取string_format?它应该是函数Fun

VoK = Fun('{name:} {age:} {gender}', 'Alice 10 F')
# the value of Vok is expected as {'name':'Alice', 'age':10, 'gender':'F'}

有没有办法获得此功能Fun

增加:

我想说,'{name:} {age:} {gender}''Alice 10 F'只是一个最简单的例子。现实情况可能更困难,space分隔符可能不存在。

从数学上讲,大多数情况都不可逆,例如:

FMT = '{key1:}{key2:}'
FoS = 'HelloWorld'

VoK可以是以下任何一个:

{'key1':'Hello','key2':'World'}
{'key1':'Hell','key2':'oWorld'}
....

因此,为了明确定义这个问题,我想补充两个条件:

1. There are always delimiters between two keys
2. All delimiters are not included in any value_of_keys. 

在这种情况下,这个问题是可以解决的(在数学上说):)

显示输入和预期输出的另一个示例:

In '{k1:}+{k2:}={k:3}', '1+1=2'    Out {'k1':1,'k2':2, 'k3':3}
In 'Hi, {k1:}, this is {k2:}', 'Hi, Alice, this is Bob' Out {'k1':'Alice', 'k2':'Bob'}

7 个答案:

答案 0 :(得分:1)

获取新字符串后,python无法确定如何创建格式化字符串。

例如:一旦您的格式"{something} {otherthing}"包含空格值并且您获得了所需的字符串,就无法区分带空格的单词是{something}还是{otherthing} <的一部分/ p>

但是,如果您了解新字符串的格式并且结果一致,则可能会使用一些黑客。

例如,在您给出的示例中:如果您确定您的单词后跟空格,然后是数字,然后是空格,然后是单词,那么您可以使用以下正则表达式来提取值:< / p>

>>> import re
>>> my_str = 'Alice 10 F'

>>> re.findall('(\w+)\s(\d+)\s(\w+)', my_str)
[('Alice', '10', 'F')] 

为了从中获取所需的dict,您可以将逻辑更新为:

>>> my_keys = ['name', 'age', 'gender']

>>> dict(zip(my_keys, re.findall('(\w+)\s(\d+)\s(\w+)', my_str)[0]))
{'gender': 'F', 'age': '10', 'name': 'Alice'}

答案 1 :(得分:1)

此代码为所有值生成字符串,但它会将字符串拆分为其组成组件。它取决于分隔符是空格,而不是包含空格的值。如果任何值包含空格,这将成为一个更难的问题。

>>> delimiters = ' '
>>> d = {k: v for k,v in zip(('name', 'age', 'gender'), 'Alice 10 F'.split(delimiters))}
>>> d
{'name': 'Alice', 'age': '10', 'gender': 'F'}

答案 2 :(得分:1)

您确实可以这样做,但格式字符串略有不同,称为正则表达式

以下是您的操作方法:

import re
# this is how you write your "format"
regex = r"(?P<name>\w+) (?P<age>\d+) (?P<gender>[MF])"
test_str = "Alice 10 F"
groups = re.match(regex, test_str)

现在您可以使用groups访问字符串的所有组件:

>>> groups.group('name')
'Alice'
>>> groups.group('age')
'10'
>>> groups.group('gender')
'F'

正则表达式是一件非常酷的事情。我建议你在网上了解更多。

答案 3 :(得分:1)

根据您的要求,我有一个解决方案。 这个解决方案的概念是:

  1. 将所有分隔符更改为相同的分隔符
  2. 使用相同的分隔符分割输入字符串
  3. 获取密钥
  4. 获取值
  5. zip键和值为dict
  6. import re
    from collections import OrderedDict
    
    def Func(data, delimiters, delimiter):
        # change all delimiters to delimiter
        for d in delimiters:
            data[0] = data[0].replace(d, delimiter)
            data[1] = data[1].replace(d, delimiter)
    
        # get keys with '{}'
        keys = data[0].split(delimiter)
        # if string starts with delimiter remove first empty element
        if keys[0] == '':
            keys = keys[1:]
    
        # get keys without '{}'
        p = re.compile(r'{([\w\d_]+):*.*}')
        keys = [p.match(x).group(1) for x in keys]
    
        # get values
        vals = data[1].split(delimiter)
        # if string starts with delimiter remove first empty element
        if vals[0] == '':
            vals = vals[1:]
    
        # pack to a dict
        result_1 = dict(zip(keys, vals))
    
        # if you need Ordered Dict
        result_2 = OrderedDict(zip(keys, vals))
    
        return result_1, result_2
    

    用法:

    In_1 = ['{k1}+{k2:}={k3:}', '1+2=3']
    delimiters_1 = ['+', '=']
    result = Func(In_1, delimiters_1, delimiters_1[0])
    # Out_1 = {'k1':1,'k2':2, 'k3':3}
    print(result)
    
    
    In_2 = ['Hi, {k1:}, this is {k2:}', 'Hi, Alice, this is Bob']
    delimiters_2 = ['Hi, ', ', this is ']
    result = Func(In_2, delimiters_2, delimiters_2[0])
    # Out_2 = {'k1':'Alice', 'k2':'Bob'}
    print(result)
    

    输出:

    ({'k3': '3', 'k2': '2', 'k1': '1'}, 
    OrderedDict([('k1', '1'), ('k2', '2'), ('k3', '3')]))
    
    ({'k2': 'Bob', 'k1': 'Alice'}, 
    OrderedDict([('k1', 'Alice'), ('k2', 'Bob')]))
    

答案 4 :(得分:1)

我写了一个功能,似乎有用:

classifier = Sequential()


classifier.add(Convolution2D(32, (3,3), input_shape = (64, 64, 3), activation='relu'))


classifier.add(MaxPool2D(pool_size = (2,2)))

classifier.add(Convolution2D(32, (3,3), activation='relu'))
classifier.add(MaxPool2D(pool_size = (2,2)))

classifier.add(Convolution2D(32, (3,3), activation='relu'))
classifier.add(MaxPool2D(pool_size = (2,2)))

classifier.add(Convolution2D(32, (3,3), activation='relu'))
classifier.add(MaxPool2D(pool_size = (2,2)))

classifier.add(Flatten())

classifier.add(Dense(units=128, activation='relu'))
classifier.add(Dropout(rate = 0.25))
classifier.add(Dense(units=128, activation='relu'))
classifier.add(Dropout(rate = 0.25))


classifier.add(Dense(units=1, activation='sigmoid'))
classifier.compile(optimizer = 'sgd', loss = 'binary_crossentropy', metrics=['accuracy'])

用法:

eg1:

import re

def Fun(fmt,res):

    reg_keys = '{([^{}:]+)[^{}]*}'
    reg_fmts = '{[^{}:]+[^{}]*}'
    pat_keys = re.compile(reg_keys)
    pat_fmts = re.compile(reg_fmts)

    keys = pat_keys.findall(fmt)
    lmts = pat_fmts.split(fmt)
    temp = res
    values = []
    for lmt in lmts:
        if not len(lmt)==0:
            value,temp = temp.split(lmt,1)
            if len(value)>0:
                values.append(value)
    if len(temp)>0:
        values.append(temp)
    return dict(zip(keys,values))

EG2:

fmt = '{k1:}+{k2:}={k:3}'
res = '1+1=2'
print Fun(fmt,res)
>>>{'k2': '1', 'k1': '1', 'k': '2'}

eg3:

fmt = '{name:} {age:} {gender}'
res = 'Alice 10 F'
print Fun(fmt,res)
>>> 

答案 5 :(得分:0)

试试这个:

import re


def fun():
   k = 'Alice 10 F'
   c = '{name:} {age:} {gender}'
   l = re.sub('[:}{]', '', c)
   d={}
   for i,j in zip(k.split(), l.split()):
       d[j]=i
   print(d)

您可以根据需要更改有趣参数并将其分配给变量。它接受您想要提供的相同字符串。并给出这样的字典:

{'name': 'Alice', 'age': '10', 'gender': 'F'}

答案 6 :(得分:0)

我建议使用**kwargs解决此问题的另一种方法,例如......

def fun(**kwargs):
    result = '{'
    for key, value in kwargs.iteritems():
        result += '{}:{} '.format(key, value)

    # stripping the last space
    result = result[:-1]
    result += '}'
    return result


print fun(name='Alice', age='10', gender='F')
# outputs : {gender:F age:10 name:Alice}

注意 kwargs 不是有序的dict,只会将参数的顺序保持在Python的3.6版本。如果您需要保留订单,那么构建解决方案很容易。