繁体   English   中英

检查变量子字符串是否在字符串中

[英]Check if a variable substring is in a string

我收到一个输入字符串,其值以两种可能的格式表示。 例如:

#short format
data = '"interval":19'

>>> "interval":19


#extended format
data = '"interval":{"t0":19,"tf":19}'

>>> "interval":{"t0":19,"tf":19}

我想检查是否使用了短格式,以防万一,将其扩展。

考虑到字符串可以由多个值组成,即

data = '"interval":19,"interval2":{"t0":10,"tf":15}'

>>> "interval":19,"interval2":{"t0":10,"tf":15}

我不能只说:

if ":{" not in data:
    #then short format is used

我想编码类似:

if ":$(a general int/float/double number)" in data:
    #extract the number
    #replace ":{number}" with the extended format

我知道如何编写替换部分的代码。 我需要实现if条件的帮助:在我看来,我将其建模为变量子字符串,其中变量部分是其中的数字,而刚性格式是$(值名称)+“:”部分。

  "some_value":19
       ^       ^
 rigid format  variable part

编辑-为什么不解析它?

我知道该字符串是“ JSON友好的”,我可以将其转换为字典,然后轻松访问值。

确实,我的代码中已经有了这个解决方案。 但是我不喜欢它,因为输入字符串可能是多级的,并且我需要独立于词典级别对生成的词典的叶值进行迭代。 后者不是一件容易的事。

所以我想知道是否存在一种直接作用于字符串的方法。

如果替换除t0tf之外的所有键,然后替换数字,则它应该起作用。
我为您展示了一个有关多级字符串的示例,可能将其放在更好的形状中:

import re

s = '"interval": 19,"t0interval2":{"t0":10,"tf":15},{"deeper": {"other_interval":23}}'

gex = '("(?!(t0|tf)")\w+":)\s*(\d+)'
new_s = re.sub(gex, r'\1 {"t0": \3, "tf": \3}', s)
print(new_s)
>>> print(new_s)
"interval": {"t0": 19, "tf": 19},"t0interval2":{"t0":10,"tf":15},{"deeper": {"other_interval": {"t0": 23, "tf": 23}}}

您可以使用正则表达式。 ("interval":)(\\d+)将查找字符串'"interval":'后跟任意位数。

让我们测试一下

data = '"interval":19,"interval2":{"t0":10,"tf":15},"interval":25'
result = re.sub(r'("interval":)(\d+)', r'xxx', data)
print(result)
# -> xxx,"interval2":{"t0":10,"tf":15},xxx

我们看到我们找到了正确的地方。 现在,我们将创建您的目标格式。 匹配的组在这里派上用场。 在正则表达式("interval":)是组1, (\\d+)是组2。

现在,我们使用这些组的内容来创建您想要的结果。

data = '"interval":19,"interval2":{"t0":10,"tf":15},"interval":25'
result = re.sub(r'("interval":)(\d+)', r'\1{"t0":\2,"tf":\2}', data)
print(result)
# -> "interval":{"t0":19,"tf":19},"interval2":{"t0":10,"tf":15},"interval":{"t0":25,"tf":25}

如果涉及浮点值,则必须将(\\d+)更改为([.\\d]+)

如果您需要任何Unicode标准单词字符,而不仅是interval您可以使用特殊序列\\w ,因为它可能是多个字符,所以表达式将是\\w+

data = '"interval":19,"interval2":{"t0":10,"tf":15},"Monty":25.4'
result = re.sub(r'("\w+":)([.\d]+)', r'\1{"t0":\2,"tf":\2}', data)
print(result)
# -> "interval":{"t0":19,"tf":19},"interval2":{"t0":{"t0":10,"tf":10},"tf":{"t0":15,"tf":15}},"Monty":{"t0":25.4,"tf":25.4}

党! 是的,我们找到了"Monty"但现在也找到了第二部分的值。 我们必须以某种方式解决此问题。 让我们来看看。 我们不希望("\\w+")前面带有{因此将使用否定的后向断言(?<!{)("\\w+") 在数字部分(\\d+)我们不需要}或其他数字,因此我们在此处使用否定的超前断言([.\\d]+)(?!})(?!\\d)

data = '"interval":19,"interval2":{"t0":10,"tf":15},"Monty":25.4'
result = re.sub(r'(?<!{)("\w+":)([.\d]+)(?!})(?!\d)', r'\1{"t0":\2,"tf":\2}', data)
print(result)
# -> "interval":{"t0":19,"tf":19},"interval2":{"t0":10,"tf":15},"Monty":{"t0":25.4,"tf":25.4}

太好了,它有效!

正则表达式功能强大且有趣,但是如果您开始添加更多约束,则可能变得难以管理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM