其他教程

其他教程

Products

当前位置:首页 > 其他教程 >

帮忙写一个正则表达式要求转换中文字为阿拉伯数字

GG网络技术分享 2025-03-18 16:14 3


问题描述:

字符串的格式为:十二斤,五十千克等,是数量+单位形式
替换完为:12斤,50千克等
不用考虑小数,但是要考虑零

C币不多了,求各位大神帮忙

网友观点:

楼主,您所提问的问题其实不是难的,观察下中文的数值写法,“十”,“百”,“千”,“万”,“亿”这些修饰符其实是一个基数。主要修饰它前面的数字,
有了前面的数字,只要想要的乘以对应的基数(10,100,1000,10000,100000000)再分别相加就可以得到对应的阿拉伯数字了,当然,中文数字对应的
阿拉伯数字还是要自己判断的。这就是思路,有了思路,只需要编写捕获到中文数值中的数字,问题就迎刃而解啦。但是,有一点说明,对应一些复杂的
中文数字的话,需要二次捕获数值再相加,例如前面的层数提到的 五千六百九十七万三千二百一十二斤,其中 五千六百九十七万。万修饰符前面的数字
也是组合而来。所以得从 五千六百九十七中再捕获一次数字。具体实现如下(c#写法,控制台显示):
正则如下:用于捕获中文数字
([零一二三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟亿]+亿)?零?([一二三四五六七八九十百千壹贰叁肆伍陆柒捌玖拾佰仟]+万)?零?([一二三四五六七八九十百壹贰叁肆伍陆柒捌玖拾佰][千仟])?零?([一二三四五六七八九十壹贰叁肆伍陆柒捌玖拾][百佰])?零?([一二三四五六七八九壹贰叁肆伍陆柒捌玖]?[十拾])?零?([一二三四五六七八九壹贰叁肆伍陆柒捌玖])?

代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

namespace regexp_help
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(\\\"请输入要转换的中文数量:\\\");
string strPreviousText = Console.ReadLine();
string strRegExp = @\\\"([零一二三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟亿]+亿)?零?([一二三四五六七八九十百千壹贰叁肆伍陆柒捌玖拾佰仟]+万)?零?([一二三四五六七八九十百壹贰叁肆伍陆柒捌玖拾佰][千仟])?零?([一二三四五六七八九十壹贰叁肆伍陆柒捌玖拾][百佰])?零?([一二三四五六七八九壹贰叁肆伍陆柒捌玖]?[十拾])?零?([一二三四五六七八九壹贰叁肆伍陆柒捌玖])?\\\";
string strAllValue = \\\"\\\";
string strSpecifier = \\\"\\\";
int dFormatValue = 0;
MatchCollection matchs = Regex.Matches(strPreviousText, strRegExp); //匹配中文数量
strAllValue = matchs[0].ToString();
strSpecifier = strPreviousText.Remove(0, matchs[0].ToString().Length);
foreach (Match match in matchs)
{
int i = 0;
GroupCollection groups = match.Groups;
foreach (Group group in groups)
{
if (i != 0) {//首个捕获组不获取,因为它是整个数字文本
if (group.ToString() != \\\"\\\")
{
dFormatValue += formatTextToNumber(group.ToString());
}
}
i++;
}
}

        Console.WriteLine(\\\"转换后的文本:{0}\\\", dFormatValue + strSpecifier);

Console.ReadKey();

}

public static int formatTextToNumber(string strVal) {

int dReturn = 0;

if (strVal.Length == 1)

{

dReturn = getNumber(strVal);

}

else {

string strNumber = strVal.Substring(0, strVal.Length - 1);

string strSpecifier = strVal.Substring(strVal.Length - 1, 1);

if (strVal.Length == 2)

{

dReturn = getNumber(strNumber) * getBaseNumber(strSpecifier);

}

//复杂数字要递归取阿拉伯数字,如五百二十万,五百二十相对于“万”修饰符是组合数字

if (strVal.Length > 2) {

string strRegExp = @\\\"([零一二三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟亿]+亿)?零?([一二三四五六七八九十百千壹贰叁肆伍陆柒捌玖拾佰仟]+万)?零?([一二三四五六七八九十百壹贰叁肆伍陆柒捌玖拾佰][千仟])?零?([一二三四五六七八九十壹贰叁肆伍陆柒捌玖拾][百佰])?零?([一二三四五六七八九壹贰叁肆伍陆柒捌玖]?[十拾])?零?([一二三四五六七八九壹贰叁肆伍陆柒捌玖])?\\\";

MatchCollection matchs = Regex.Matches(strNumber, strRegExp); //匹配中文数量

foreach (Match match in matchs)

{

int i = 0;

GroupCollection groups = match.Groups;

foreach (Group group in groups)

{

if (i != 0)

{//首个捕获组不获取,因为它是整个数字文本

if (group.ToString() != \\\"\\\")

{

dReturn += formatTextToNumber(group.ToString());

}

}

i++;

}

}

dReturn *= getBaseNumber(strSpecifier);

}

}

return dReturn;

}

//获取单数字文本对应阿拉伯数字

public static int getNumber(string strVal) {

int dFormatValue = 0;

switch (strVal)

{

case \\\"一\\\":

case \\\"壹\\\":

dFormatValue = 1;

break;

case \\\"二\\\":

case \\\"贰\\\":

dFormatValue = 2;

break;

case \\\"三\\\":

case \\\"叁\\\":

dFormatValue = 3;

break;

case \\\"四\\\":

case \\\"肆\\\":

dFormatValue = 4;

break;

case \\\"五\\\":

case \\\"伍\\\":

dFormatValue = 5;

break;

case \\\"六\\\":

case \\\"陆\\\":

dFormatValue = 6;

break;

case \\\"七\\\":

case \\\"柒\\\":

dFormatValue = 7;

break;

case \\\"八\\\":

case \\\"捌\\\":

dFormatValue = 8;

break;

case \\\"九\\\":

case \\\"玖\\\":

dFormatValue = 9;

break;

case \\\"十\\\":

case \\\"拾\\\":

dFormatValue = 10;

break;

default:

dFormatValue = 0;

break;

}

return dFormatValue;

}

//获取修饰符对用基数

public static int getBaseNumber(string strVal) {

int dFormatValue = 10;

switch (strVal)

{

case \\\"十\\\":

case \\\"拾\\\":

dFormatValue = 10;

break;

case \\\"百\\\":

case \\\"佰\\\":

dFormatValue = 100;

break;

case \\\"千\\\":

case \\\"仟\\\":

dFormatValue = 1000;

break;

case \\\"万\\\":

dFormatValue = 10000;

break;

case \\\"亿\\\":

dFormatValue = 100000000;

break;

default:

dFormatValue = 10;

break;

}

return dFormatValue;

}

}

}

测试截图:
测试图例1:

测试图例2:

测试图例3:

正则有可以筛选特定中文的吗?不太清楚 不过你这种的话 对字符串循环一下 用个switch进行下替换就行了

String newStr = \\\"\\\";
switch(str){
case: “零”: newStr +=0;

......
default: newStr += str; //单位点等不处理
}

正则表达式实现起来有点难吧,你看看这个方法

public double DecodeMoneyCn(string AText)
{
AText = AText.Replace(\\\"亿亿\\\", \\\"兆\\\");
AText = AText.Replace(\\\"万万\\\", \\\"亿\\\");
AText = AText.Replace(\\\"点\\\", \\\"元\\\");
AText = AText.Replace(\\\"块\\\", \\\"元\\\");
AText = AText.Replace(\\\"毛\\\", \\\"角\\\");
double vResult = 0;
double vNumber = 0; // 当前数字
double vTemp = 0;
int vDecimal = 0; // 是否出现小数点
foreach (char vChar in AText)
{
int i = \\\"零一二三四五六七八九\\\".IndexOf(vChar);
if (i < 0) i = \\\"洞幺两三四五六拐八勾\\\".IndexOf(vChar);
if (i < 0) i = \\\"零壹贰叁肆伍陆柒捌玖\\\".IndexOf(vChar);
if (i > 0)
{
vNumber = i;
if (vDecimal > 0)
{
vResult += vNumber * Math.Pow(10, -vDecimal);
vDecimal++;
vNumber = 0;
}
}
else
{
i = \\\"元十百千万亿\\\".IndexOf(vChar);
if (i < 0) i = \\\"整拾佰仟万亿兆\\\".IndexOf(vChar);
if (i == 5) i = 8;
if (i == 6) i = 12;
if (i > 0)
{
if (i >= 4)
{
vTemp += vNumber;
if (vTemp == 0) vTemp = 1;
vResult += vTemp * Math.Pow(10, i);
vTemp = 0;
}
else vTemp += vNumber * Math.Pow(10, i);
}
else
{
i = \\\"元角分\\\".IndexOf(vChar);
if (i > 0)
{
vTemp += vNumber;
vResult += vTemp * Math.Pow(10, -i);
vTemp = 0;
}
else if (i == 0)
{
vTemp += vNumber;
vResult += vTemp;
vDecimal = 1;
vTemp = 0;
}
}
vNumber = 0;
}
}
return vResult + vTemp + vNumber;
}

private void button1_Click(object sender, EventArgs e)
{
string[] vTestText = {
\\\"十二点五六\\\",
\\\"一亿零一万零五\\\",
\\\"四万万\\\",
\\\"九十八亿七千六百五十四万三千二百一十\\\",
\\\"五元一角四分\\\", \\\"壹佰元整\\\",
\\\"三千五百万\\\",
\\\"九块二毛\\\"};
foreach (string vText in vTestText)
{
Console.WriteLine(\\\"DecodeMoneyCn(\\\\\"{0}\\\\\")={1}\\\", vText,
DecodeMoneyCn(vText));
}

//输出

//DecodeMoneyCn(\\\"十二点五六\\\")=2.56

//DecodeMoneyCn(\\\"一亿零一万零五\\\")=100010005

//DecodeMoneyCn(\\\"四万万\\\")=400000000

//DecodeMoneyCn(\\\"九十八亿七千六百五十四万三千二百一十\\\")=9876543210

//DecodeMoneyCn(\\\"五元一角四分\\\")=5.14

//DecodeMoneyCn(\\\"壹佰元整\\\")=100

//DecodeMoneyCn(\\\"三千五百万\\\")=35000000

//DecodeMoneyCn(\\\"九块二毛\\\")=9.2

//DecodeMoneyCn(\\\"一兆\\\")=1000000000000

}

String newStr = \\\"\\\";
switch(str){
case: “零”: newStr +=0;

......
default: newStr += str; //单位点等不处理
}

正则有可以筛选特定中文的吗?不太清楚 不过你这种的话 对字符串循环一下 用个switch进行下替换就行了

String newStr = \\\"\\\";
switch(str){
case: “零”: newStr +=0;

......
default: newStr += str; //单位点等不处理
}

String newStr = \\\"\\\";
switch(str){
case: “零”: newStr +=0;

......
default: newStr += str; //单位点等不处理
}

str.replace(\\\"零\\\", \\\"0\\\").replace(\\\"一\\\", \\\"1\\\")....;

String newStr = \\\"\\\";
switch(str){
case: “零”: newStr +=0;

......
default: newStr += str; //单位点等不处理
}

String newStr = \\\"\\\";
switch(str){
case: “零”: newStr +=0;

......
default: newStr += str; //单位点等不处理
}

一个一个替换 replace(\\\"一\\\",“1”)

(?=.*(.*)|.*(.*))^[a-zA-Z0-9\\u4e00-\\u9fa5()()]*$|^[a-zA-Z0-9\\u4e00-\\u9fa5]*$
匹配规则:
1. 完全匹配输入中文,英文,数字以及英文半角括号和中文全角括号;
2. 匹配如有括号必须成对;

(?=.*(.*)|.*(.*))^[a-zA-Z0-9\\u4e00-\\u9fa5()()]*$|^[a-zA-Z0-9\\u4e00-\\u9fa5]*$
匹配规则:
1. 完全匹配输入中文,英文,数字以及英文半角括号和中文全角括号;
2. 匹配如有括号必须成对;

小兄弟,問問題態度要端正,別話語中帶著譏諷.最近剛好在做正則表達式的分析,你這個用正則分析不出來的.中文不支持特定字符,一到十等等,也可能是我不知道.我可以給你提供個思路,很簡單就能解決你的問題:
1字符串切割,\\\"五十斤,六十克,三十千克\\\" 單位是有限的,C語言有字符切割,函數strtok;
2 得到若干個字符串\\\"五十斤\\\"\\\"六十克\\\"\\\"三十千克\\\" 然後 中文零到九對應0-9 十對應10;
3這樣最多有十個switch case 語句;

這樣做也不難.

 String str = \\\"十二万零四百一十公斤\\\";

String newStr = \\\"\\\";

for (int i = 0; i < str.length(); i++) {

char st = str.charAt(i);

switch (st) {

case \'零\':

newStr += \'0\';

break;

case \'一\':

newStr += \'1\';

break;

case \'二\':

newStr += \'2\';

break;

case \'三\':

newStr += \'3\';

break;

case \'四\':

newStr += \'4\';

break;

case \'十\':

if (i + 1 != str.length()) {

newStr += \'1\';

}

break;

case \'百\':

break;

case \'千\':

break;

case \'万\':

break;

default:

newStr += st;

break;

}

}

System.out.println(newStr);

}

用python写程序,怎么用正则表达式匹配出一个字符串中的所有数字,包括整数和浮点数?

r'\\-*\\d+(?:\\.\\d+)?'

标签:

提交需求或反馈

Demand feedback