2011-10-18 38 views
0

我想开始知道如何去符合下列条件创建一个正则表达式:正则表达式验证,并提取字符串以十进制或分数

  1. 字符串必须以小数或分数
  2. 启动
  3. 十进制应该是正数,最多可以保留两位小数
  4. 分数应该是它自己的一个分数或一个整数和分数,即1 1/2,3/4,并用空格分隔。 (可能是冷静,如果有人写1和1/2,这新的将是1 1/2,但不是必需
  5. 列表项

我想验证一个字符串,或为十进制开始或一部分和得到提取的值在它外面

有效实例

"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) 

无效实例

"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})*(.*)$ 

只是不知道如何正确地加入2,它可以更好地优化?和无效的一个仍然解析

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

问候DotnetShadow

+0

我已编辑我的帖子,包括我目前为止如果有帮助 – DotnetShadow

回答

3

我下面的作品与你的上述实例(使用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后加上分子除以分母)。

您还可以为其他受支持的“单元”以及其他支持的“连接词”添加其他模式。

编辑:根据我的意见添加了我的建议。

+0

而实际上,您可能会使用(? \ d +)代替整个数字部分... – Reddog

+0

也许移动第一个“\ s” (空格)以某种方式加入“JoinWord”捕获组。 – Reddog

+0

非常感谢你,非常感谢你。我可以从这里学到很多 – DotnetShadow

1

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

  1. 编写函数IsFraction(字符串s),检查字符串是否是有效的分数(例如,它可以是3/2?)。
  2. 拆分输入字符串,检查最后一项不是任何数字 - 这将是单位。
  3. 删除列表中的所有非数字和非分数项目。
  4. 验证剩余的物品数量是否小于3.
  5. 如果物品的数量是2,首先验证是自然数,第二是小数。 - >结果
  6. 如果count为1,请验证它是分数还是小数。 - >结果

更多的时间(可能)为初步写作,但更容易维护和扩展。

P.S.使用int.TryParsedecimal.TryParse以及在IsFraction之内。

+0

感谢您的好选择会尝试 – DotnetShadow