[英]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友好的”,我可以将其转换为字典,然后轻松访问值。
确实,我的代码中已经有了这个解决方案。 但是我不喜欢它,因为输入字符串可能是多级的,并且我需要独立于词典级别对生成的词典的叶值进行迭代。 后者不是一件容易的事。
所以我想知道是否存在一种直接作用于字符串的方法。
如果替换除t0
, tf
之外的所有键,然后替换数字,则它应该起作用。
我为您展示了一个有关多级字符串的示例,可能将其放在更好的形状中:
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.