【问题标题】:Is there a way to detect words without searching for whitespace or underscores有没有办法在不搜索空格或下划线的情况下检测单词
【发布时间】:2021-04-19 00:44:03
【问题描述】:

我正在尝试编写一个用于生成 python 类的 CLI。其中一部分需要验证用户输入中提供的标识符,而对于 python,这需要确保标识符符合标识符的 pep8 最佳实践/标准 - 具有 CapsCases 的类、具有 all_lowercase_with_underscores 的字段、具有等等的包和模块等等 -

# it is easy to correct when there is a identifier
# with underscores or whitespace and correcting for a class

def package_correct_convention(item):
    return item.strip().lower().replace(" ","").replace("_","")

但是当标记之间没有空格或下划线时,我不确定如何正确地将标识符中每个单词的首字母大写。是否可以在不使用 AI 或类似的东西的情况下实现类似的东西:

比如说:

# providing "ClassA" returns "classa" because there is no delimiter between "class" and "a"
def class_correct_convention(item):
    if item.count(" ") or item.count("_"):
        # checking whether space or underscore was used as word delimiter.
        if item.count(" ") > item.count("_"):
            item = item.split(" ")
        elif item.count(" ") < item.count("_"):
            item = item.split("_")
        item = list(map(lambda x: x.title(), item))
        return ("".join(item)).replace("_", "").replace(" ","")
    # if there is no white space, best we can do it capitalize first letter 
    return item[0].upper() + item[1:]

【问题讨论】:

  • 提供ClassA 实际上返回ClassA。您能否提供一个清晰的示例(或一些使问题清晰的示例),以及预期的结果以及与实际结果有何不同?此外,显然需要有一些区分标记,如大写。毕竟,'classa' 真的是 'ClassA' 还是作者打算使用 'ClasSa' 或 'Classa'(用任何可能意味着什么的语言)?
  • 你基本上需要一个分词器和一个接受词的字典。它需要回溯。而且它总是启发式的,因为有有效的字符串可以以不止一种方式进行标记,例如hislap 是否应该标记为 hiSlaphisLap?旁注:Python 已经提供了 str.capitalizestr.title 方法,它们可以为您完成很多工作,因此您可能需要研究它们。

标签: python conventions pep8


【解决方案1】:

嗯,使用基于 AI 的方法将是困难的,不完美的,大量的工作。如果它不值得,也许还有更简单且肯定相当有效的方法。

我知道最坏的情况是"todelineatewordsinastringlikethat"

我建议您逐行下载一个英文文本文件,然后按以下方式进行:

import re

string = "todelineatewordsinastringlikethat" 

#with open("mydic.dat", "r") as msg:
#    lst = msg.read().splitlines()

lst = ['to','string','in'] #Let's say the dict contains 3 words

lst = sorted(lst, key=len, reverse = True)

replaced = []

for elem in lst:

    if elem in string: #Very fast
        replaced_str = " ".join(replaced) #Faster to check elem in a string than elem in a list
        capitalized = elem[0].upper()+elem[1:] #Prepare your capitalized word

        if elem not in replaced_str: #Check if elem could be a substring of something you replaced already
            string = re.sub(elem,capitalized,string) 

        elif elem in replaced_str: #If elem is a sub of something you replaced, you'll protect
            protect_replaced = [item for item in replaced if elem in item] #Get the list of replaced items containing the substring elem

            for protect in protect_replaced: #Uppercase the whole word to protect, as we do a case sensitive re.sub()
                string = re.sub(protect,protect.upper(),string)

            string = re.sub(elem,capitalized,string)

            for protect in protect_replaced: #Deprotect by doing the reverse, full uppercase to capitalized
                string = re.sub(protect.upper(),protect,string)

        replaced.append(capitalized) #Append replaced element in the list
        
print (string)

输出:

TodelIneatewordsInaStringlikethat
#You see that String has been protected but not delIneate, cause it was not in our dict.

这当然不是最佳的,但对于一个肯定不会像 AI 那样呈现的问题(输入准备在 AI 中非常重要),其性能肯定与 AI 相当。

请注意,反向排序单词列表很重要。因为您想首先检测完整的字符串单词,而不是 sub。就像在 beforehand 中一样,您想要完整的,而不是 beforeand

【讨论】:

    猜你喜欢
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 2019-06-17
    • 1970-01-01
    • 2017-09-20
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多