如何安全地截断带引号的字符串?

How to safely truncate a quoted string?

我有以下字符串:

Customer sale 88% in urm 50

引用urllib.parse.quote,变成:

Customer%20sale%2088%25%20in%20urm%2050%27

然后我需要将其长度限制为最多 30 个字符,我使用 value[:30]

问题是它变成了 "Customer%20sale%2088%25%20in%",这是无效的:
最后一个 % 是引用字符串中 %20 的一部分,并使其成为无效的引用字符串。

我无法控制原始字符串,最终结果需要最大长度为 30,所以我无法预先截断它。

哪种方法可行?

如何寻找悬空的百分号?

value = value[:30]
if value[-1] == "%":
    value = value[:-1]
elif value[-2] == "%":
    value = value[:-2]
print(value)

urllib.quote 使用 RFC 3986 中定义的百分比编码。这意味着编码字符将始终采用 "%" HEXDIG HEXDIG.

形式

因此,您只需在最后两个字符中查找 % 符号即可删除编码的任何尾随剩余部分。

例如:

>>> s=quote("Customer sale 88% in urm 50")[:30]
>>> n=s.find('%', -2)
>>> s if n < 0 else s[:n]
'Customer%20sale%2088%25%20in'

编码后的字符串将始终采用%HH的格式。您希望字符串长度最大为 30 个字符,并使用有效编码。所以,可能是我能想到的最佳解决方案:

from urllib.parse import quote
string= "Customer sale 88% in urm 50"
string=quote(string)
string=string[:string[:30].rfind("%")]
print(string)

输出:

string=string[:string[:30].rfind("%")]

解法:

编码后,你可能会得到一个任意长度的字符串,下面一行代码就可以非常优化的实现你的需求。

 string=string[:string[:30].rfind("%")]

解释:

它首先从quoted string中提取30 characters,然后从右端搜索%。从右端开始 % 的位置将用于提取字符串。瞧!你得到了你的结果。

替代方法:

除了string=string[:string[:30].rfind("%")]你也可以这样做string=string[:string.rfind("%",0,30)]

注意:我提取了字符串并将其存储回去以展示它是如何工作的,如果你不想存储那么你可以简单地使用 like print(string[:string[:30].rfind("%")]) 来显示结果

希望对您有所帮助...

如何将单个字符放在列表中,然后计数和剥离? 粗略示例:

from urllib import quote

s = 'Customer sale 88% in urm 50'

res = []
for c in s:
    res.append(quote(c))

print res # ['C', 'u', 's', 't', 'o', 'm', 'e', 'r', '%20', 's', 'a', 'l', 'e', '%20', '8', '8', '%25', '%20', 'i', 'n', '%20', 'u', 'r', 'm', '%20', '5', '0']
print len(res)

current_length = 0
for item in res:
    current_length += len(item)

print current_length # 39

while current_length > 30:
    res = res[:-1]
    current_length = 0
    for item in res:
        current_length += len(item)

print "".join(res) # Customer%20sale%2088%25%20in

这样你就不会在引号字符的中间截断。如果您将来需要不同的长度,只需修改 while 循环即可。好吧,代码也可以变得更干净 ;)