为字符串中的所有数字添加下标格式

Adding subscript formatting to all numbers in a string

我正在尝试编写一个简单的脚本来遍历输入字符串并将字符串中的所有数字转换为下标数字。

这是我对输入字符串进行迭代的最新尝试 item 并且应该创建一个包含下标数字的新字符串来代替原始字符串中的数字。也许这是不可能的,但我似乎无法结合 Unicode 和格式化字符串文字表达式来完成这项工作。

item= 'H2O'
new=[]

sub = u'\u208'

for i,x in enumerate(item):
    if x.isdigit():
        sub=u'{x}'.format(sub)
        new.append(sub)
    else:
        new.append(x)
new=''.join(new)

new

我收到以下错误:

File "<ipython-input-48-1d7d4a7394db>", line 4
    sub = u'\u208'
         ^
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-4: truncated \uXXXX escape

最后,我想执行以下 "conversion" 以获得输入字符串 (H2O) 的 "number-subscripted" 版本 (H₂O):

H2O --> H₂O

关于我做错了什么或者是否有更好的方法来做这件事有什么想法吗? 谢谢!

您可以使用 str.maketrans()

u'\u2080'u'\u2089'代表0到9的数字

sub=str.maketrans("0123456789", "₀₁₂₃₄₅₆₇₈₉")
_str='C3H8O3'
_str=_str.translate(sub)
print(_str)

产出

'C₃H₈O₃'

在您的代码中 sub=u'\u208' 应该是 sub=u'\u2082'。简单的替换就足够了。

_str='H2O'
sub=u'\u2082'
for char in _str:
    if char.isdigit():
        _str=_str.replace(char,sub)
print(_str)

'H₂O'

将普通值构建到下标值字典中。

sub=u'\u2080'
norm_to_sub={}
for norm in '0123456789':
    norm_to_sub[norm]=sub
    sub=chr(ord(sub)+1)

print(norm_to_sub)

{'0': '₀', '1': '₁', '2': '₂', '3': '₃', '4': '₄', '5': '₅', '6': '₆', '7': '₇', '8': '₈', '9': '₉'}

根据 wjandrea 的建议,您可以这样做。

sub = 0x2080
norm_to_sub={}
for norm in range(10):
    norm_to_sub[norm] = ord(sub + norm)

{'0': '₀', '1': '₁', '2': '₂', '3': '₃', '4': '₄', '5': '₅', '6': '₆', '7': '₇', '8': '₈', '9': '₉'}

您甚至可以创建函数。

def change_to_sub(number):
    sub=0x2080
    return ''.join(chr(sub+int(num)) for num in str(number))

print(change_to_sub(1232454353654))

'₁₂₃₂₄₅₄₃₅₃₆₅₄'

从方法论的角度来看,可以将操作减少两两步。我认为这也有助于提高可读性,如果将来需要,可以让您更轻松地向量化您的操作:

>>> mapping = {"0": "₀", "1": "₁", "2": "₂", "3": "₃", "4": "₄", 
               "5": "₅", "6": "₆", "7": "₇", "8": "₈", "9": "₉"}
>>> formula = "CH3CH2CH2CH3"
>>> "".join([mapping.get(x) or x for x in list(formula)])
'CH₃CH₂CH₂CH₃'

关于您遇到的 unicode 错误,我在 jupyter 中遇到了同样的错误。但是将字符 from wikipedia 直接复制粘贴到我的笔记本单元格中似乎可以解决问题。

如果您想实际使用 unicode 代码,您似乎缺少代码的最后一个字符。所以应该是'\u2080'(python3)或者u'\u2080'(python2),就是'\u2081',等等

您的实现没有意义,但您的方法有道理。你可以做的是取数字的整数值,加上0x2080得到下标代码点,然后转换为字符。

import string

item = 'H2O'
sub = 0x2080
new = ''.join(chr(sub + int(c)) if c in string.digits else c for c in item)
print(new)  # -> H₂O

我正在使用 string.digits here because str.isdigit 做的比你想要的更多。对于无法转换为整数的字符串,它将 return 为真,例如 '₂' 本身。