带下划线的 Canot 切片/索引 unicode 字符串

Canot slice/index unicode strings with underscores

提问人:tutizeri 提问时间:11/10/2023 最后编辑:tutizeri 更新时间:11/10/2023 访问量:67

问:

我有这个Unicode字符串:

my_string = "₁ᴀa̲a̲̲"

如何对其进行索引和切片以制作其他 Unicode 字符串?

如果我运行

print([x for x in my_string])
['₁', 'ᴀ', 'a', '̲', 'a', '̲', '̲']

当我预期时

['₁', 'ᴀ', 'a̲', '̲a̲̲']

这打印

my_string[3]
'̲'

当我预期时

a̲̲

我试过定义

my_string = u"₁ᴀa̲a̲̲"

但是 VSCode 会自动删除u

我需要作为缓冲区,根据他的人类可读索引来组合其他字符串。my_string

python-3.x unicode 切片

评论

0赞 hiro protagonist 11/10/2023
也许您可以先使用 UnicodeData.normalize 对字符串进行规范化?不确定这是否有帮助......
0赞 tutizeri 11/10/2023
@hiro我试过的主角,但它不适用于下划线字符。my_string = unicodedata.normalize("NFKD",u"₁ᴀa̲a̲̲")
0赞 Andj 11/11/2023
应该是还是?a̲̲
0赞 tutizeri 11/11/2023
@Andj“a_”和“a__”,如我认为stackoverflow破坏了unicode所示。print([x for x in my_string]) ['₁', 'ᴀ', 'a', '̲', 'a', '̲', '̲']
0赞 Andj 11/11/2023
您的字符串是 U+0061 U+0332 U+0332,它应该呈现为 a,在 a 下方有一条组合低线,然后在第一条组合低线下方有另一条组合低线。通常,我会看到 U+0061 U+0333。但是,我只倾向于在现实生活中的书目数据中看到 U+0332 和 U+0333。

答:

3赞 mozway 11/10/2023 #1

您可以使用 \X 正则表达式和正则表达式模块:findall

import regex

out = regex.findall(r'\X', my_string)

输出:

['₁', 'ᴀ', 'a̲', 'a̲̲']
0赞 Konrad 11/10/2023 #2

在字符串注释中表达的建议是最可行的;但是,您可能还需要考虑以下字符:normalizeencoding

import unicodedata
for x in unicodedata.normalize('NFD', my_string):
    print("Normalized: " + x)
    print("Encoded: " + str(x.encode('ascii', errors="backslashreplace"))) 
    print("Encoded/decoded: " + x.encode('ascii', 'ignore').decode('ascii'))

你会看到区别:

Normalized: ₁
Encoded: b'\\u2081'
Encoded/decoded: 
Normalized: ᴀ
Encoded: b'\\u1d00'
Encoded/decoded: 
Normalized: a
Encoded: b'a'
Encoded/decoded: a
Normalized: ̲
Encoded: b'\\u0332'
Encoded/decoded: 
Normalized: a
Encoded: b'a'
Encoded/decoded: a
Normalized: ̲
Encoded: b'\\u0332'
Encoded/decoded: 
Normalized: ̲
Encoded: b'\\u0332'
Encoded/decoded: 

笔记

作为对评论的回应,如果希望比较更多有问题的字符串,传递可能是一个可行的解决方案。errors="backslashreplace"

评论

1赞 mozway 11/10/2023
这将丢弃组成和非 ascii 字符(如),这似乎不是想要的。
0赞 Konrad 11/10/2023
@mozway 你说得有道理,如果 OP 希望对更挑剔的角色进行精细控制,那么可以使用这个解决方案。虽然,这需要手动映射潜在有问题的字符。