簡體   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