正则表达式验证并提取以小数或分数开头的字符串

本文关键字:开头 字符串 小数 验证 提取 正则表达式 | 更新日期: 2023-09-27 18:11:45

我想知道如何创建具有以下条件的正则表达式:

  1. 字符串必须以小数或分数开头
  2. 小数应该是正数,最多2位小数
  3. 分数应该是一个分数本身或一个整数和分数,即1 1/2,3/4,并由空格分隔。(如果有人写了1又1/2,这可能很酷,它是新的,它将是1 1/2,但没有必要
  4. )列表项

我想验证字符串以小数或分数开头,并从中提取值

<<p> 有效例子/strong>
"1 cup" = VALID = Extracted values: (1) (cup)
".5 cup" = VALID = Extracted values: (0.5) (cup)
"1.0 cup" = VALID = Extracted values: (1.0) (cup)
"1.10 cup" = VALID = Extracted values: (1.10) (cup)
"1/2 cup" = VALID = Extracted values: (1/2) (cup)
"1 1/2 cup" = VALID = Extracted values: (1 1/2) (cup)
"1 and 1/2 cup" = VALID = Extracted values: (1 1/2) (cup)
"1 and a 1/2 cup" = VALID = Extracted values: (1 1/2) (cup)
"1 & 1/2 cup" = VALID = Extracted values: (1 1/2) (cup)
<<p> 无效的例子/strong>
"1 1/2 1/4 1/4 cup" = INVALID (only allow whole and fraction, or one fraction)
"1.034 cup" = INVALID (2 decimal places only)    
"cup 1/2" = INVALID (not the start of the string)

编辑到目前为止我有什么:

解析分数:

'd*'s*(and*|and a*|'s*)'d+'/?'d*(.*)$
解析小数:

^'d{0,2}('.'d{1,2})?$

我的组合版本:

('d*'s*&|and*|and a*|'s*'s*'d+'/?'d*)|('d{0,2}'.'d{1,2})*(.*)$

只是不知道如何正确地连接这两个,它可以更好地优化?,无效的仍然解析

任何帮助将不胜感激,谢谢

问候DotnetShadow

正则表达式验证并提取以小数或分数开头的字符串

下面的例子对我来说是有效的(使用Regex Hero进行测试):

^(?<WholeNumber>'d+){0,1}(?:'s(?<JoinWord>&|and|and'sa)?'s?)?(?<Decimal>'.'d{1,2})?(?<Fraction>(?<Numerator>'d+)'/(?<Denominator>'d+)){0,1}(?:'s(?<Unit>cup))$

您将注意到我对各个组件使用了命名捕获组。我将留给您解析这些组并有意义地将它们连接起来(例如,将整数与十进制值除以100的值相加,并将分子除以分母的值相加)。

您还可以为其他支持的"unit"和其他支持的"joinWord"添加额外的模式。

编辑:根据我的评论添加了我的建议

我不认为你需要正则表达式来解决这个问题。考虑以下解决方案:

  1. 编写函数IsFraction(string s)检查string是否是一个有效的分数(例如,它可以是3/2吗?)
  2. 分割输入字符串,检查最后一项不是任何类型的数字-那将是单位。
  3. 从列表中删除所有非数字和非分数项。
  4. 确认剩余项目数小于3。
  5. 如果项目计数为2,首先验证是自然数,其次是分数。结果->
  6. 如果count为1,验证它是分数或小数。结果->

更多的时间(可能)用于初始写入,但更容易维护和扩展。

注:

使用int.TryParsedecimal.TryParseIsFraction