1use regex::Regex;
5use std::collections::HashMap;
9use std::str;
10use rust_decimal::prelude::*;
11
12static CHINESE_CHAR_NUMBER_LIST: [(&str, i32); 29] = [
14 ("幺", 1),
15 ("零", 0),
16 ("一", 1),
17 ("二", 2),
18 ("两", 2),
19 ("三", 3),
20 ("四", 4),
21 ("五", 5),
22 ("六", 6),
23 ("七", 7),
24 ("八", 8),
25 ("九", 9),
26 ("十", 10),
27 ("百", 100),
28 ("千", 1000),
29 ("万", 10000),
30 ("亿", 100000000),
31 ("壹", 1),
32 ("贰", 2),
33 ("叁", 3),
34 ("肆", 4),
35 ("伍", 5),
36 ("陆", 6),
37 ("柒", 7),
38 ("捌", 8),
39 ("玖", 9),
40 ("拾", 10),
41 ("佰", 100),
42 ("仟", 1000),
43];
44
45static CHINESE_PURE_COUNTING_UNIT_LIST: [&str; 5] = ["十", "百", "千", "万", "亿"];
46
47static CHINESE_PURE_NUMBER_LIST: [&str; 13] = [
48 "幺", "一", "二", "两", "三", "四", "五", "六", "七", "八", "九", "十", "零",
49];
50
51fn core_ch_to_digits(chinese_chars_to_trans: String) -> String {
53 let chinese_chars = chinese_chars_to_trans;
54 let total: String;
55 let mut temp_val = "".to_string(); let mut counting_unit: i32 = 1; let mut counting_unit_from_string: Vec<i32> = vec![1]; let mut temp_val_int: i32;
59 let chinese_char_number_dict: HashMap<&str, i32> =
60 CHINESE_CHAR_NUMBER_LIST.into_iter().collect();
61
62 let mut temp_total: i32 = 0;
63 for i in (0..chinese_chars.chars().count()).rev() {
66 let char_to_get = chinese_chars.chars().nth(i).unwrap().to_string();
68 let val_from_hash_map = chinese_char_number_dict.get(char_to_get.as_str());
69
70 match val_from_hash_map {
71 Some(val_from_hash_map) => {
72 let val = *val_from_hash_map;
73 if val >= 10 && i == 0_usize {
74 if val > counting_unit {
76 counting_unit = val;
77 temp_total = temp_total + val;
78 counting_unit_from_string.push(val);
79 } else {
80 counting_unit_from_string.push(val);
81 let max_value_option = counting_unit_from_string.iter().max();
82 let max_value = max_value_option.unwrap();
83 counting_unit = max_value * val;
84 }
85 } else if val >= 10 {
86 if val > counting_unit {
87 counting_unit = val;
88 counting_unit_from_string.push(val);
89 } else {
90 counting_unit_from_string.push(val);
91 let max_value_option = counting_unit_from_string.iter().max();
93 let max_value = max_value_option.unwrap();
94 counting_unit = max_value * val;
95 }
96 } else {
97 if i > 0 {
98 let pre_val_temp_option = chinese_char_number_dict.get(
100 chinese_chars
101 .chars()
102 .nth(i - 1)
103 .unwrap()
104 .to_string()
105 .as_str(),
106 );
107 match pre_val_temp_option {
108 Some(pre_val_temp_option) => {
109 let pre_val_temp = *pre_val_temp_option;
110 if pre_val_temp < 10 {
111 temp_val = val.to_string() + &temp_val;
113 } else {
114 temp_val_int =
118 (val.to_string() + &temp_val).parse::<i32>().unwrap();
119 temp_total = temp_total + counting_unit * temp_val_int;
120 temp_val = "".to_string();
122 }
123 }
124 None => {}
125 }
126 } else {
127 if counting_unit == 1 {
130 temp_val = val.to_string() + &temp_val;
131 } else {
132 temp_val_int = (val.to_string() + &temp_val).parse::<i32>().unwrap();
133 temp_total = temp_total + counting_unit * temp_val_int;
134 }
135 }
136 }
137 }
138 None => println!("No string in number"),
139 }
140 }
141 if temp_total == 0 {
143 if counting_unit > 10 {
144 total = counting_unit.to_string();
146 } else {
147 if temp_val != "" {
149 total = temp_val;
150 } else {
151 total = temp_total.to_string();
153 }
154 }
155 } else {
156 total = temp_total.to_string();
158 }
159
160 return total;
161}
162
163fn check_number_seg(chinese_number_list: &Vec<String>, origin_text: &String) -> Vec<String> {
165 let mut new_chinese_number_list: Vec<String> = [].to_vec();
166 let mut temp_pre_text: String = "".to_string();
168 let mut temp_mixed_string: String;
169 let seg_len = chinese_number_list.len();
170 if seg_len > 0 {
171 if chinese_number_list[0].starts_with("分之") {
173 new_chinese_number_list.push(
175 (&chinese_number_list[0][2..(chinese_number_list[0].chars().count())]).to_string(),
176 );
177 } else {
178 new_chinese_number_list.push(chinese_number_list.get(0).unwrap().to_string())
179 }
180
181 if seg_len > 1 {
182 for i in 1..seg_len {
183 if (chinese_number_list[i]).starts_with("分之") {
185 temp_mixed_string = chinese_number_list.get(i - 1).unwrap().to_string()
187 + &chinese_number_list[i];
188
189 if origin_text.contains(&temp_mixed_string.to_string()) {
190 if temp_pre_text != "" {
192 if CHINESE_PURE_COUNTING_UNIT_LIST
194 .iter()
195 .any(|&x| x == (&temp_pre_text.chars().last().unwrap().to_string()))
196 {
197 let temp_last_chinese_number =
199 new_chinese_number_list.last().unwrap().to_string();
200 let temp_new_chinese_number_list_len =
202 new_chinese_number_list.len();
203 let temp_last_chinese_number_char_list: Vec<char> =
204 temp_last_chinese_number.chars().collect();
205 new_chinese_number_list[temp_new_chinese_number_list_len - 1] =
207 temp_last_chinese_number_char_list
208 [0..(temp_last_chinese_number_char_list.len() - 1)]
209 .iter()
210 .collect();
211 new_chinese_number_list.push(
213 temp_pre_text
214 .chars()
215 .nth(temp_pre_text.chars().count() - 1)
216 .unwrap()
217 .to_string() + &chinese_number_list[i],
218 );
219 } else {
220 new_chinese_number_list
222 .push((&chinese_number_list[i][2..]).to_string())
223 }
224 } else {
225 if new_chinese_number_list.len() > 0 {
227 let temp_new_chinese_number_list_len =
230 new_chinese_number_list.len();
231 new_chinese_number_list[temp_new_chinese_number_list_len - 1] =
232 temp_mixed_string;
233 } else {
234 new_chinese_number_list.push(temp_mixed_string);
235 }
236 }
237 } else {
238 new_chinese_number_list.push((&chinese_number_list[i][2..]).to_string())
241 }
242 temp_pre_text = chinese_number_list.get(i).unwrap().to_string();
244 } else {
245 new_chinese_number_list.push(chinese_number_list.get(i).unwrap().to_string());
247 temp_pre_text = "".to_string();
249 }
250 }
251 }
252 }
253 return new_chinese_number_list;
254}
255
256fn check_chinese_number_reasonable(ch_number: &String) -> bool {
257 if ch_number.chars().count() > 0 {
258 for i in CHINESE_PURE_NUMBER_LIST {
263 if ch_number.contains(&i.to_string()) {
264 return true;
265 }
266 }
267 }
268 return false;
269}
270
271static DIGITS_CHAR_CHINESE_DICT_KEY: [&str; 14] = [
275 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "%", "‰", "‱", ".",
276];
277static DIGITS_CHAR_CHINESE_DICT: [(&str, &str); 14] = [
278 ("0", "零"),
279 ("1", "一"),
280 ("2", "二"),
281 ("3", "三"),
282 ("4", "四"),
283 ("5", "五"),
284 ("6", "六"),
285 ("7", "七"),
286 ("8", "八"),
287 ("9", "九"),
288 ("%", "百分之"),
289 ("‰", "千分之"),
290 ("‱", "万分之"),
291 (".", "点"),
292];
293
294static CHINESE_PER_COUNTING_STRING_LIST: [&str; 3] = ["百分之", "千分之", "万分之"];
295
296static TRADITIONAL_CONVERT_DICT_STATIC: [(&str, &str); 9] = [
297 ("壹", "一"),
298 ("贰", "二"),
299 ("叁", "三"),
300 ("肆", "四"),
301 ("伍", "五"),
302 ("陆", "六"),
303 ("柒", "七"),
304 ("捌", "八"),
305 ("玖", "九"),
306];
307static SPECIAL_TRADITIONAL_COUNTING_UNIT_CHAR_DICT_STATIC: [(&str, &str); 5] = [
308 ("拾", "十"),
309 ("佰", "百"),
310 ("仟", "千"),
311 ("萬", "万"),
312 ("億", "亿"),
313];
314static SPECIAL_NUMBER_CHAR_DICT: [(&str, &str); 2] = [("两", "二"), ("俩", "二")];
315static CHINESE_SIGN_LIST: [&str; 4] = ["正", "负", "+", "-"];
317
318fn digits_to_ch_chars(mixed_string_list: &Vec<String>) -> Vec<String> {
320 let mut result_list: Vec<String> = vec![];
321 let digits_char_chinese_dict: HashMap<&str, &str> =
322 DIGITS_CHAR_CHINESE_DICT.into_iter().collect();
323 for i in mixed_string_list.iter() {
325 let mut mixed_string = i.to_string();
326 if mixed_string.starts_with(".") {
327 mixed_string = "0".to_string() + &mixed_string;
328 }
329 for key in DIGITS_CHAR_CHINESE_DICT_KEY.iter() {
330 if mixed_string.contains(&key.to_string()) {
331 mixed_string = mixed_string.replace(
332 key,
333 digits_char_chinese_dict
334 .get(key)
335 .unwrap()
336 .to_string()
337 .as_str(),
338 );
339 for kk in CHINESE_PER_COUNTING_STRING_LIST.iter() {
342 if mixed_string.contains(&kk.to_string()) {
343 mixed_string = kk.to_string() + &mixed_string.replace(kk, "");
344 }
345 }
346 }
347 }
348 result_list.push(mixed_string);
349 }
350
351 return result_list;
352}
353
354fn traditional_text_convert_func(ch_string: &String, simplif_convert_switch: bool) -> String {
358 let mut ch_string_list: Vec<char> = ch_string.chars().collect();
360
361 let string_length = ch_string.chars().count();
362 let mut char_to_get: String;
363 let traditional_convert_dict: HashMap<&str, &str> =
364 TRADITIONAL_CONVERT_DICT_STATIC.into_iter().collect();
365 let special_traditional_counting_unit_char_dict: HashMap<&str, &str> =
366 SPECIAL_TRADITIONAL_COUNTING_UNIT_CHAR_DICT_STATIC
367 .into_iter()
368 .collect();
369 let special_number_char_dict: HashMap<&str, &str> =
370 SPECIAL_NUMBER_CHAR_DICT.into_iter().collect();
371 if simplif_convert_switch {
372 for i in 0..ch_string_list.len() {
373 char_to_get = ch_string_list[i].to_string();
376 let value = traditional_convert_dict.get(char_to_get.as_str());
377 match value {
378 Some(value) => {
379 ch_string_list[i] = (*value).chars().nth(0).unwrap();
380 }
381 None => {}
382 }
383 }
384 }
385 if string_length > 1 {
386 for i in 0..string_length {
388 char_to_get = ch_string_list[i].to_string();
390 let value = special_traditional_counting_unit_char_dict.get(char_to_get.as_str());
392 match value {
394 Some(value) => {
395 if i == 0 {
396 if CHINESE_PURE_NUMBER_LIST
397 .iter()
398 .any(|&x| x == ch_string_list[i + 1].to_string())
399 {
400 ch_string_list[i] = (*value).chars().nth(0).unwrap();
401 }
402 } else if i == (string_length - 1) {
403 if CHINESE_PURE_NUMBER_LIST
404 .iter()
405 .any(|&x| x == ch_string_list[i - 1].to_string())
406 {
407 ch_string_list[i] = (*value).chars().nth(0).unwrap();
408 }
409 } else {
410 if (CHINESE_PURE_NUMBER_LIST
411 .iter()
412 .any(|&x| x == ch_string_list[i - 1].to_string()))
413 || (CHINESE_PURE_NUMBER_LIST
414 .iter()
415 .any(|&x| x == ch_string_list[i + 1].to_string()))
416 {
417 ch_string_list[i] = (*value).chars().nth(0).unwrap();
418 }
419 }
420 }
421 None => {}
422 }
423 char_to_get = ch_string_list[i].to_string();
425 let value = special_number_char_dict.get(char_to_get.as_str());
426 match value {
428 Some(value) => {
429 if i == 0 {
430 if CHINESE_PURE_COUNTING_UNIT_LIST
431 .iter()
432 .any(|&x| x == ch_string_list[i + 1].to_string())
433 {
434 ch_string_list[i] = (*value).chars().nth(0).unwrap();
435 }
436 } else if i == (string_length - 1) {
437 if CHINESE_PURE_COUNTING_UNIT_LIST
438 .iter()
439 .any(|&x| x == ch_string_list[i - 1].to_string())
440 {
441 ch_string_list[i] = (*value).chars().nth(0).unwrap();
442 }
443 } else {
444 if (CHINESE_PURE_COUNTING_UNIT_LIST
445 .iter()
446 .any(|&x| x == ch_string_list[i - 1].to_string()))
447 || (CHINESE_PURE_COUNTING_UNIT_LIST
448 .iter()
449 .any(|&x| x == ch_string_list[i + 1].to_string()))
450 {
451 ch_string_list[i] = (*value).chars().nth(0).unwrap();
452 }
453 }
454 }
455 None => {}
456 }
457 }
458 }
459 let final_ch_string_list: String = ch_string_list.iter().collect();
460
461 return final_ch_string_list;
462}
463
464fn standard_ch_number_convert(ch_number_string: String) -> String {
468 let ch_number_string_list: Vec<char> = ch_number_string.chars().collect();
469
470 let mut new_ch_number_string_list: String = ch_number_string;
471
472 if ch_number_string_list.len() > 2 {
474 let ten_number_index = ch_number_string_list
476 .iter()
477 .position(|&x| x == "十".chars().nth(0).unwrap());
478 match ten_number_index {
479 Some(ten_number_index) => {
480 if ten_number_index == 0_usize {
481 new_ch_number_string_list = "一".to_string() + &new_ch_number_string_list;
482 } else {
483 if !(CHINESE_PURE_NUMBER_LIST.iter().any(|&x| {
485 x == ch_number_string_list[(ten_number_index - 1)]
486 .to_string()
487 .as_str()
488 })) {
489 let temp_left_part: String =
490 ch_number_string_list[0..ten_number_index].iter().collect();
491 let temp_right_part: String =
492 ch_number_string_list[ten_number_index..].iter().collect();
493 new_ch_number_string_list = temp_left_part + "一" + &temp_right_part;
494 }
495 }
496 }
497 None => {}
498 }
499
500 let temp_new_ch_number_string_list: Vec<char> = new_ch_number_string_list.chars().collect();
505
506 let last_counting_unit = CHINESE_PURE_COUNTING_UNIT_LIST.iter().position(|&x| {
507 x == temp_new_ch_number_string_list[temp_new_ch_number_string_list.len() - 2]
508 .to_string()
509 .as_str()
510 });
511 match last_counting_unit {
513 Some(last_counting_unit) => {
514 if last_counting_unit >= 1_usize {
515 if last_counting_unit == 4_usize {
518 new_ch_number_string_list = new_ch_number_string_list + &"千万".to_string();
519 } else {
520 new_ch_number_string_list = new_ch_number_string_list
521 + &CHINESE_PURE_COUNTING_UNIT_LIST[last_counting_unit - 1].to_string();
522 }
523 }
524 }
525 None => {}
526 }
527 }
528 let mut per_count_switch = false;
530 let temp_new_ch_number_string_list: Vec<char> = new_ch_number_string_list.chars().collect();
531 if temp_new_ch_number_string_list.len() > 1 {
532 let _first_char_check_result = ["千", "万", "百"]
536 .iter()
537 .position(|&x| x == temp_new_ch_number_string_list[0].to_string().as_str());
538 match _first_char_check_result {
539 Some(_first_char_check_result) => {
540 for i in 1..temp_new_ch_number_string_list.len() {
541 if CHINESE_PURE_NUMBER_LIST
543 .iter()
544 .any(|&x| x == temp_new_ch_number_string_list[i].to_string().as_str())
545 {
546 per_count_switch = true;
547 } else {
548 per_count_switch = false;
549 break;
551 }
552 }
553 if per_count_switch {
554 let temp_left_part_string: String =
555 temp_new_ch_number_string_list[0..1].iter().collect();
556 let temp_right_part_string: String =
557 temp_new_ch_number_string_list[1..].iter().collect();
558 new_ch_number_string_list =
559 temp_left_part_string + "分之" + &temp_right_part_string;
560 }
561 }
562 None => {}
563 }
564 }
565
566 return new_ch_number_string_list;
567}
568
569fn check_sign_seg(chinese_number_list: &Vec<String>) -> Vec<String> {
571 let mut new_chinese_number_list: Vec<String> = vec![];
572 let mut temp_sign = "".to_string();
573 for i in 0..chinese_number_list.len() {
574 let mut new_ch_number_string = temp_sign.clone() + &chinese_number_list[i];
576 let temp_chinese_number_list: Vec<char> = new_ch_number_string.chars().collect();
577 if temp_chinese_number_list.len() > 1 {
578 let last_string: String = temp_chinese_number_list
579 [(temp_chinese_number_list.len() - 1)..]
580 .iter()
581 .collect();
582 if CHINESE_SIGN_LIST.iter().any(|&x| x == last_string.as_str()) {
584 temp_sign = last_string;
585 new_ch_number_string = temp_chinese_number_list
588 [..(temp_chinese_number_list.len() - 1)]
589 .iter()
590 .collect();
591 } else {
592 temp_sign = "".to_string();
593 }
594 }
595 new_chinese_number_list.push(new_ch_number_string)
596 }
597 return new_chinese_number_list;
598}
599
600pub struct C2DResultStruct {
601 pub input_text: String,
602 pub replaced_text: String,
603 pub ch_number_string_list: Vec<String>,
604 pub digits_string_list: Vec<String>,
605}
606
607static TAKING_CHINESE_DIGITS_MIX_RE_RULES_STRING: &str = concat!(
613 r#"(?:(?:分之){0,1}(?:\+|\-){0,1}[正负]{0,1})(?:(?:(?:\d+(?:\.\d+){0,1}(?:[%‰‱]){0,1}"#,
614 r#"|\.\d+(?:[%‰‱]){0,1}){0,1}(?:(?:(?:[一二三四五六七八九十千万亿兆幺零百]+(?:点[一二三四五六七八九万亿兆幺零]+){0,1})"#,
615 r#"|(?:点[一二三四五六七八九万亿兆幺零]+))))|(?:(?:\d+(?:\.\d+){0,1}(?:[%‰‱]){0,1}|\.\d+(?:[%‰‱]){0,1})"#,
616 r#"(?:(?:(?:[一二三四五六七八九十千万亿兆幺零百]+"#,
617 r#"(?:点[一二三四五六七八九万亿兆幺零]+){0,1})|(?:点[一二三四五六七八九万亿兆幺零]+))){0,1}))"#
618);
619
620static CHINESE_SIGN_DICT_STATIC: [(&str, &str); 4] =
621 [("负", "-"), ("正", "+"), ("-", "-"), ("+", "+")];
622
623static CHINESE_CONNECTING_SIGN_STATIC: [(&str, &str); 3] = [(".", "."), ("点", "."), ("·", ".")];
624
625fn chinese_to_digits(chinese_chars_to_trans: String, percent_convert: bool) -> String {
627 let mut final_total: String;
631 let mut convert_result_list: Vec<String> = vec![];
632 let mut chinese_chars_list_by_div: Vec<String> = vec![];
633
634 let chinese_sign_dict: HashMap<&str, &str> = CHINESE_SIGN_DICT_STATIC.into_iter().collect();
635 let chinese_connecting_sign_dict: HashMap<&str, &str> =
636 CHINESE_CONNECTING_SIGN_STATIC.into_iter().collect();
637
638 if chinese_chars_to_trans.contains("分之") {
639 let temp_split_result: Vec<&str> = chinese_chars_to_trans.split("分之").collect();
640 for s in temp_split_result {
641 chinese_chars_list_by_div.push(s.to_string());
642 }
643 } else {
644 chinese_chars_list_by_div.push(chinese_chars_to_trans);
645 }
646
647 for k in 0..chinese_chars_list_by_div.len() {
648 let mut temp_chinese_char: String = chinese_chars_list_by_div[k].to_string();
649
650 let chinese_char: Vec<char> = temp_chinese_char.chars().collect();
652 let mut sign = "".to_string();
656 let mut char_to_get: String;
657 for i in 0..chinese_char.len() {
658 char_to_get = chinese_char[i].to_string();
659 let value = chinese_sign_dict.get(char_to_get.as_str());
660 match value {
661 Some(value) => {
662 sign = value.to_string();
663 temp_chinese_char = temp_chinese_char.replace(&char_to_get, "");
665 }
666 None => {}
667 }
668 }
669 let mut string_contain_dot = false;
675 let mut left_of_dot_string = "".to_string();
676 let mut right_of_dot_string = "".to_string();
677 for (key, _) in &chinese_connecting_sign_dict {
678 if temp_chinese_char.contains(&key.to_string()) {
679 let chinese_chars_dot_split_list: Vec<&str> =
680 temp_chinese_char.split(key).collect();
681 left_of_dot_string = chinese_chars_dot_split_list[0].to_string();
682 right_of_dot_string = chinese_chars_dot_split_list[1].to_string();
683 string_contain_dot = true;
684 break;
685 }
686 }
687 let mut convert_result: String;
688 if !string_contain_dot {
689 convert_result = core_ch_to_digits(temp_chinese_char);
690 } else {
691 let mut temp_buf: String;
693 let temp_right_digits: String;
694 let mut temp_count_string = "".to_string();
697 let list_of_right: Vec<char> = right_of_dot_string.chars().collect();
698 for ii in (0..(list_of_right.len())).rev() {
699 let _find_counting_unit_index_result = CHINESE_PURE_COUNTING_UNIT_LIST
700 .iter()
701 .position(|&x| x == list_of_right[ii].to_string().as_str());
702 match _find_counting_unit_index_result {
703 Some(_find_counting_unit_index_result) => {
704 temp_count_string = list_of_right[ii].to_string() + &temp_count_string;
705 }
706 None => {
707 right_of_dot_string = list_of_right[0..(ii + 1)].iter().collect();
708 break;
709 }
710 }
711 }
712
713 let mut temp_count_num = 1.0;
714 if temp_count_string != "" {
715 let temp_num = core_ch_to_digits(temp_count_string).parse::<f32>().unwrap();
716 temp_count_num = temp_num;
717 }
718
719 if left_of_dot_string == "" {
720 temp_buf = "0.".to_string();
724 temp_right_digits = core_ch_to_digits(right_of_dot_string);
725 temp_buf = temp_buf + &temp_right_digits;
726 convert_result = temp_buf;
727 } else {
728 temp_buf = core_ch_to_digits(left_of_dot_string);
729 temp_buf = temp_buf + ".";
730 temp_right_digits = core_ch_to_digits(right_of_dot_string);
731 temp_buf = temp_buf + &temp_right_digits;
732 convert_result = temp_buf;
733 }
734
735 let temp_str_to_float = convert_result.parse::<f32>().unwrap();
736 convert_result = (temp_str_to_float * temp_count_num).to_string();
737 }
738 if convert_result == "" {
740 convert_result = "1".to_string();
741 }
742 convert_result = sign + &convert_result;
743 let new_convert_result_temp: Vec<char> = convert_result.chars().collect();
746 let new_buf: String;
747 if convert_result.ends_with(".0") {
748 new_buf = new_convert_result_temp[0..new_convert_result_temp.len() - 2]
749 .iter()
750 .collect();
751 } else {
752 new_buf = convert_result;
753 }
754 convert_result_list.push(new_buf);
755 }
756 if convert_result_list.len() > 1 {
757 if percent_convert {
759 let temp_float1 = Decimal::from_str(&convert_result_list[1]).unwrap();
764 let temp_float0 = Decimal::from_str(&convert_result_list[0]).unwrap();
765 final_total = (temp_float1 / temp_float0).to_string();
766 } else {
767 if convert_result_list[0] == "100" {
768 final_total = convert_result_list[1].to_string() + "%"
769 } else if convert_result_list[0] == "1000" {
770 final_total = convert_result_list[1].to_string() + "‰"
771 } else {
772 final_total = convert_result_list[1].to_string() + "/" + &convert_result_list[0]
773 }
774 }
775 } else {
776 final_total = convert_result_list[0].to_string()
777 }
785 if final_total.contains("."){
787 final_total = final_total.trim_end_matches("0").to_string();
788 final_total = final_total.trim_end_matches(".").to_string();
789 }
790
791
792 return final_total;
793}
794
795fn take_chinese_number_from_string(
830 ch_text_string: &str,
831 percent_convert: bool,
832 traditional_convert: bool,
833) -> C2DResultStruct {
834 let mut ch_number_string_list: Vec<String> = vec![];
835
836 let converted_string: String =
873 traditional_text_convert_func(&ch_text_string.to_string(), traditional_convert);
874
875 let mut reg_match_result: Vec<String> = vec![];
877 let taking_chinese_digits_mix_re_rules: Regex =
878 Regex::new(TAKING_CHINESE_DIGITS_MIX_RE_RULES_STRING).unwrap();
879 for cap in taking_chinese_digits_mix_re_rules.captures_iter(&converted_string) {
922 reg_match_result.push(cap[0].to_string());
923 }
924
925 let mut temp_text: String;
926 let mut ch_number_string_list_temp: Vec<String> = vec![];
927 for i in 0..reg_match_result.len() {
928 temp_text = reg_match_result[i].to_string();
929 ch_number_string_list_temp.push(temp_text);
930 }
931 ch_number_string_list_temp = check_number_seg(&ch_number_string_list_temp, &converted_string);
934
935 ch_number_string_list_temp = check_sign_seg(&ch_number_string_list_temp);
937
938 let origin_ch_number_take: Vec<String> = ch_number_string_list_temp.clone();
940
941 ch_number_string_list_temp = digits_to_ch_chars(&ch_number_string_list_temp);
943
944 let mut origin_ch_number_for_output: Vec<String> = vec![];
948 for i in 0..ch_number_string_list_temp.len() {
949 temp_text = ch_number_string_list_temp[i].to_string();
951 if check_chinese_number_reasonable(&temp_text) {
952 ch_number_string_list.push(temp_text);
954 origin_ch_number_for_output.push(origin_ch_number_take[i].to_string());
956 }
957 }
959
960 ch_number_string_list_temp = vec![];
964 for i in 0..ch_number_string_list.len() {
965 ch_number_string_list_temp.push(standard_ch_number_convert(
966 ch_number_string_list[i].to_string(),
967 ));
968 }
969
970 let mut digits_string_list: Vec<String> = vec![];
974 let mut replaced_text = converted_string;
975 let mut temp_ch_to_digits_result: String;
976 if ch_number_string_list_temp.len() > 0 {
977 for i in 0..ch_number_string_list_temp.len() {
978 temp_ch_to_digits_result =
979 chinese_to_digits(ch_number_string_list_temp[i].to_string(), percent_convert);
980 digits_string_list.push(temp_ch_to_digits_result);
981 }
982 let mut tuple_to_replace: Vec<_> = origin_ch_number_for_output
986 .iter()
987 .zip(digits_string_list.iter())
988 .enumerate()
989 .collect();
990
991 tuple_to_replace.sort_by_key(|(_, (_, z))| z.chars().count());
992
993 for i in 0..digits_string_list.len() {
1004 replaced_text = replaced_text.replace(
1009 tuple_to_replace[i].1 .0, tuple_to_replace[i].1 .1, );
1012 }
1013 }
1014
1015 let final_result = C2DResultStruct {
1016 input_text: ch_text_string.to_string(),
1017 replaced_text: replaced_text.to_string(),
1018 ch_number_string_list: origin_ch_number_for_output,
1019 digits_string_list: digits_string_list,
1020 };
1021 return final_result;
1022}
1023
1024pub fn take_number_from_string(
1025 ch_text_string: &str,
1026 percent_convert: bool,
1027 traditional_convert: bool,
1028) -> C2DResultStruct {
1029 let final_result: C2DResultStruct =
1034 take_chinese_number_from_string(ch_text_string, percent_convert, traditional_convert);
1035 return final_result;
1036}
1037
1038#[test]
1039fn test_core_ch_to_digits() {
1040 assert_eq!(core_ch_to_digits("三百四十二万".to_string()), "3420000")
1042}
1043#[test]
1044fn test_check_number_seg() {
1045 let a1 = vec![
1046 "百".to_string(),
1047 "分之5".to_string(),
1048 "负千".to_string(),
1049 "分之15".to_string(),
1050 ];
1051 let a2 = "百分之5负千分之15".to_string();
1052 let a3 = vec!["百分之5".to_string(), "负千分之15".to_string()];
1053 assert_eq!(check_number_seg(&a1, &a2), a3)
1054}
1055
1056#[test]
1057fn test_check_chinese_number_reasonable() {
1058 let a2 = "千千万万".to_string();
1059 assert_eq!(check_chinese_number_reasonable(&a2), false)
1060}