【问题标题】:Python 3.x How extract alphabetic representation of numbers from stringPython 3.x 如何从字符串中提取数字的字母表示
【发布时间】:2020-07-09 09:29:53
【问题描述】:

我需要解析可能包含字母数字的文本。例如

"I`ve got sixty six tasks"

"There is four people"

我的目标是获取子字符串sixty sixfour

在互联网上有很多方法将数字字符串表示形式转换为整数,而无需额外的文本。但我需要下一个结果:

find_numbers("Hello world") -> []
find_numbers("Hello five world") -> ['five']

【问题讨论】:

    标签: python-3.x parsing text nltk


    【解决方案1】:

    您需要为此使用 2 个库:

    word2number 将从字符串中提取数字。

    例如

    >>> print(w2n.word_to_num("Hello five world"))
    5
    

    然后您可以使用num2words 库将输出转换回单词:

    >>> print(num2words(5))
    five
    

    【讨论】:

    • 不合适,因为如果我有字符串i have three apples and two bananas w2n return 5
    • @БогданМарченко 这个数字有什么限制?例如有最大值吗?例如不超过 10
    • 可能是不同的数字,如@9​​87654328@、sixty sixthree millionthree hundred twenty eight
    【解决方案2】:

    由于无聊,我修改了word_to_num的一个版本。一些错误检查不包括在内,但您可以根据需要添加。

    我不会详细介绍它的工作原理,但本质上,它将数字分成组,然后将这些组中的每一个输入word2numbers 算法。

    american_number_system = {
        'zero': 0,
        'one': 1,
        'two': 2,
        'three': 3,
        'four': 4,
        'five': 5,
        'six': 6,
        'seven': 7,
        'eight': 8,
        'nine': 9,
        'ten': 10,
        'eleven': 11,
        'twelve': 12,
        'thirteen': 13,
        'fourteen': 14,
        'fifteen': 15,
        'sixteen': 16,
        'seventeen': 17,
        'eighteen': 18,
        'nineteen': 19,
        'twenty': 20,
        'thirty': 30,
        'forty': 40,
        'fifty': 50,
        'sixty': 60,
        'seventy': 70,
        'eighty': 80,
        'ninety': 90,
        'hundred': 100,
        'thousand': 1000,
        'million': 1000000,
        'billion': 1000000000
    }
    
    
    def number_formation(number_words):
        numbers = []
        for number_word in number_words:
            numbers.append(american_number_system[number_word])
        if len(numbers) == 4:
            return (numbers[0] * numbers[1]) + numbers[2] + numbers[3]
        elif len(numbers) == 3:
            return numbers[0] * numbers[1] + numbers[2]
        elif len(numbers) == 2:
            if 100 in numbers:
                return numbers[0] * numbers[1]
            else:
                return numbers[0] + numbers[1]
        else:
            return numbers[0]
    
    def get_decimal_sum(decimal_digit_words):
        decimal_number_str = []
        for dec_word in decimal_digit_words:
            if(dec_word not in decimal_words):
                return 0
            else:
                decimal_number_str.append(american_number_system[dec_word])
        final_decimal_string = '0.' + ''.join(map(str,decimal_number_str))
        return float(final_decimal_string)
    
    def to_num(string):
        string = string.replace('-', ' ')
        string = string.replace(',', ' ')
        words = string.strip().split()
    
        number_groups = []
        current_word = []
        numbers = []
    
        for word in words:
            if word in american_number_system:
                current_word.append(word)
            elif word.lower() != 'and' and len(current_word):
                number_groups.append(current_word)
                current_word = []
        
        if len(current_word):
            number_groups.append(current_word)
    
        for clean_numbers in number_groups:
            clean_decimal_numbers = []
            total_sum = 0
    
            if clean_numbers.count('point') == 1:
                clean_decimal_numbers = clean_numbers[clean_numbers.index('point')+1:]
                clean_numbers = clean_numbers[:clean_numbers.index('point')]
    
            billion_index = clean_numbers.index('billion') if 'billion' in clean_numbers else -1
            million_index = clean_numbers.index('million') if 'million' in clean_numbers else -1
            thousand_index = clean_numbers.index('thousand') if 'thousand' in clean_numbers else -1
    
            if len(clean_numbers) == 1:
                    total_sum += american_number_system[clean_numbers[0]]
    
            else:
                if billion_index > -1:
                    billion_multiplier = number_formation(clean_numbers[0:billion_index])
                    total_sum += billion_multiplier * 1000000000
    
                if million_index > -1:
                    if billion_index > -1:
                        million_multiplier = number_formation(clean_numbers[billion_index+1:million_index])
                    else:
                        million_multiplier = number_formation(clean_numbers[0:million_index])
                    total_sum += million_multiplier * 1000000
    
                if thousand_index > -1:
                    if million_index > -1:
                        thousand_multiplier = number_formation(clean_numbers[million_index+1:thousand_index])
                    elif billion_index > -1 and million_index == -1:
                        thousand_multiplier = number_formation(clean_numbers[billion_index+1:thousand_index])
                    else:
                        thousand_multiplier = number_formation(clean_numbers[0:thousand_index])
                    total_sum += thousand_multiplier * 1000
    
                if thousand_index > -1 and thousand_index != len(clean_numbers)-1:
                    hundreds = number_formation(clean_numbers[thousand_index+1:])
                elif million_index > -1 and million_index != len(clean_numbers)-1:
                    hundreds = number_formation(clean_numbers[million_index+1:])
                elif billion_index > -1 and billion_index != len(clean_numbers)-1:
                    hundreds = number_formation(clean_numbers[billion_index+1:])
                elif thousand_index == -1 and million_index == -1 and billion_index == -1:
                    hundreds = number_formation(clean_numbers)
                else:
                    hundreds = 0
                total_sum += hundreds
            
            if len(clean_decimal_numbers) > 0:
                decimal_sum = get_decimal_sum(clean_decimal_numbers)
                total_sum += decimal_sum
            
            numbers.append(total_sum)
        
        return numbers
    
    tests = []
    tests.append(to_num("I`ve got sixty six tasks"))
    tests.append(to_num("There is four people"))
    tests.append(to_num("Hello world"))
    tests.append(to_num("Hello five world"))
    tests.append(to_num("i have three apples and two bananas"))
    tests.append(to_num("three hundred twenty eight"))
    
    print(tests)
    

    从这里您可以使用num2words 来反转结果。

    编辑:

    实际上,重新阅读您的问题,比这容易得多。你只需要找到这些数字的位置并提取它们。

    american_number_system = {
        'zero': 0,
        'one': 1,
        'two': 2,
        'three': 3,
        'four': 4,
        'five': 5,
        'six': 6,
        'seven': 7,
        'eight': 8,
        'nine': 9,
        'ten': 10,
        'eleven': 11,
        'twelve': 12,
        'thirteen': 13,
        'fourteen': 14,
        'fifteen': 15,
        'sixteen': 16,
        'seventeen': 17,
        'eighteen': 18,
        'nineteen': 19,
        'twenty': 20,
        'thirty': 30,
        'forty': 40,
        'fifty': 50,
        'sixty': 60,
        'seventy': 70,
        'eighty': 80,
        'ninety': 90,
        'hundred': 100,
        'thousand': 1000,
        'million': 1000000,
        'billion': 1000000000
    }
    
    def extract_num(raw_string):
        string = raw_string.replace('-', ' ')
        string = string.replace(',', ' ')
        words = string.strip().split()
    
        word_pos = False
        numbers = []
        current_pos = 0
    
        for word in words:
            if word in american_number_system:
                if word_pos:
                    length = len(word) + 1
                    word_pos = (word_pos[0], word_pos[1] + length)
                else:
                    length = len(word)
                    word_pos = (current_pos, current_pos + length)
            elif word.lower() == 'and' and word_pos:
                word_pos = (word_pos[0], word_pos[1] + 4)
            elif word_pos:
                numbers.append(raw_string[word_pos[0]:word_pos[1]])
                word_pos = False
            
            current_pos += len(word) + 1
        
        if word_pos:
            numbers.append(raw_string[word_pos[0]:])
        
        return numbers
    
    
    tests = []
    tests.append(extract_num("I`ve got sixty six tasks"))
    tests.append(extract_num("There is four people"))
    tests.append(extract_num("Hello world"))
    tests.append(extract_num("Hello five world"))
    tests.append(extract_num("i have three apples and two bananas"))
    tests.append(extract_num("three hundred twenty eight"))
    
    print(tests)
    

    【讨论】:

      猜你喜欢
      • 2017-07-30
      • 2021-05-01
      • 2018-12-13
      • 1970-01-01
      • 2016-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多