【问题标题】:How to convert somewhat arbitrary strings to valid human-readable identifiers?如何将任意字符串转换为有效的人类可读标识符?
【发布时间】:2016-11-28 14:50:02
【问题描述】:

我有一长串人类可读的字符串,其中一些包含一些非 ASCII 甚至非拉丁字符。

'Count €'  
'Contains äüöß'
'Y tu mamá también.'
'что'

但我使用的服务要求名称仅包含 a-z、A-Z、0-9、.、_、(空格)。

将它们转换为在这些要求下有效的唯一名称的简洁方法是什么?

我们希望尽可能地保持人类可读性。例如,理想情况下不要将. 更改为full stop,也不要将& 更改为u38。我们不能简单地删除无效字符或变音符号。例如:

'Count euro symbol'
'Contains a with umlaut u with umlaut o with umlaut sharp s'
'Y tu mama_ tambie_n.'
'cyrillic small letter che ...'

以下是限制条件:
- 必须是 Python(2 和 3)
- 必须不需要安装包
- 必须保持唯一性(如果有边缘情况没有,那很好)
- 必须简洁

(注意:'Y tu mama tambien.' 是不可接受的,因为它可能会打破唯一性约束。)

将任意字符串转换为有效的类名或标识符有一些相似之处。

【问题讨论】:

    标签: python unicode nlp naming-conventions naming


    【解决方案1】:

    谷歌搜索“python 字符名称”会弹出unicodedata 模块。所以一个开始的地方是这样的

    import string
    import unicodedata
    
    ALLOWED = set(string.ascii_letters + string.digits + '. _')
    sentences = ['Count €', 'Contains äüöß', 'Y tu mamá también.', 'что']
    
    def encode(s):
        return ''.join([unicodedata.name(c).replace(" ","_")+"_"
                       if c not in ALLOWED else c for c in s])
    
    for s in sentences:
        print(s)
        print(encode(s))
    

    这给了我

    Count €
    Count EURO_SIGN_
    Contains äüöß
    Contains LATIN_SMALL_LETTER_A_WITH_DIAERESIS_LATIN_SMALL_LETTER_U_WITH_DIAERESIS_LATIN_SMALL_LETTER_O_WITH_DIAERESIS_LATIN_SMALL_LETTER_SHARP_S_
    Y tu mamá también.
    Y tu mamLATIN_SMALL_LETTER_A_WITH_ACUTE_ tambiLATIN_SMALL_LETTER_E_WITH_ACUTE_n.
    что
    CYRILLIC_SMALL_LETTER_CHE_CYRILLIC_SMALL_LETTER_TE_CYRILLIC_SMALL_LETTER_O_
    

    只需多做一点工作(为转义选择合适的分隔符),您就可以保证这可以完美地往返,但这留给读者作为练习。

    【讨论】:

    • 非常感谢。我目前也有类似的东西,同样使用unicode.name,但你的公式更简洁。我仍然对单线抱有希望。
    • @A.M.Bittlingmayer:这很愚蠢。我们是开发人员(大概),而不是专业的代码爱好者。如果有的话,上面的代码太短:它没有文档,没有往返,等等。我会拒绝我在代码审查中提交的代码,并与提交它的人进行有针对性的对话!
    • 我不想混淆它,但也许有一个聪明的方法可以干净地做到这一点或现有的库。我们拭目以待。
    • 顺便说一下,unicodedata.name(c) 不幸需要被包裹在 try/except 中。 (我用'ord' + str(ord(c))'处理它。)
    • 此代码不满足唯一性要求。 encode(u'John EURO_SIGN_') == encode(u'John €')
    猜你喜欢
    • 2011-11-18
    • 2013-02-21
    • 2012-03-31
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多