有趣的数字转化问题:将中文表述的数字转化为阿拉伯数字

求助图片

前几天,有个在香港读研当RA的学妹,问了我一个在帮忙导师处理文本数据的时候遇到的问题,她表示这个问题有点超出了她目前的编程能力范围。我初看了下,是一个文本转化的问题,它的特殊之处,是不能直接进行替换,而第一步需要定位出数字所在的区域范围。我决定协助她一起解决这个问题,也顺便帮她提升了处理文本数据类型的能力。


求助图片2
接下来,我简单把她的需求点描述一下

总问题:将中文文本的数字串转化为阿拉伯数字
分问题:
1、三位数以上的,直接转化;(由于这个问题是处理公司名的,所以一般是直接写数字不写单位,写单位的情况数字也不复杂)
2、两位数的转化,因为带有省略说法,如十二、二十等,要特殊处理;
3、一位数的时候,数字之前有第字才转化,否则不转化。


首先我先mock了一个简单的例子来定位输入输出。

输入:二十八日第一名乘客带着三只狗搭上了八四七公交车。
输出:28日第1名乘客带着三只狗搭上了847公交车。

这里有四处数字,只有一处的数字是不需要转化的。

接下来我来说一下我的思路:

第一步:先将输入字符串的数字区域和非数字区域进行区分,最终分块。
第二步:写一个数字转化的函数,实现从中文数字转化为阿拉伯数字的转化的逻辑,覆盖的情况需要尽量得全,以免出bug。
第三步:从左到右遍历文本块,将需要进行转化的文本块转化后,进行拼接,最终得到目标的输出字符串。

用python初步实现了以上的流程

# -*- coding: utf-8 -*-  

#输入:二十八号第一名乘客带着三只小狗搭上了八四七公交车。
#输出:28号第1名乘客带着三只小狗搭上了847公交车。

def list2dict(array):
	#将数字区域分离出来
	array.append(1-array[-1])
	out = []
	flag = 0
	for i in range(1,len(array)):
		if(array[i] != array[i-1]):
			out.append([array[i-1],flag,i-1])
			flag = i
	return out

def number_transfer(inp):
	#将中文数字转化为阿拉伯数字
	numbers = {u"零":0,u"一":1,u"二":2,u"三":3,u"四":4,u"五":5,u"六":6,u"七":7,u"八":8,u"九":9}
	unit = [u"十",u"百",u"千",u"万"]
	out = ""
	for i in inp:
		if i not in unit:
			out += str(numbers[i])
	return out



def str_transfer(inp):
	out = ""
	numbers = [u"零",u"一",u"二",u"三",u"四",u"五",u"六",u"七",u"八",u"九",u"十",u"百",u"千",u"万"]
	num_list = []
	for i in inp:
		if i in numbers:
			num_list.append(1)
		else:
			num_list.append(0)
	num_list = list2dict(num_list)
	for l in num_list:
		if (l[0] == 1 and l[2] - l[1] != 0) or (l[2] - l[1] == 0 and inp[l[1] - 1] in [u"第"]):
			out += number_transfer(inp[l[1]:(l[2] + 1)])
		else:
			out += inp[l[1]:(l[2] + 1)]
	return out


if __name__ == '__main__':
	inp = u"二十八号第一名乘客带着三只小狗搭上了八四七公交车。";
	out = str_transfer(inp)
	print out
comments powered by Disqus