[英]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.