我正在寻找构建一个正则表达式,匹配2个十进制数(必须包含小数点),最多由6个单词分隔(在这种情况下,单词意味着任何有空格的东西)。数字也必须< 1000,我想捕捉2个数字
这是我在正则表达式上的尝试,但它根本不匹配。
regex = /([0-9]{1,3}(\.[0-9]+))([^0-9\s] ){1,6}([0-9]{1,3}(\.[0-9]+))\b/i
范例:
str = 'Min Hourly Rate 33.33 Max Hourly Range: 45.55'
regex.match(str) #returns nil
此外,本发明还提供了一种方法,
str = 'Min Hourly Rate 33.33 Max Hourly Range: 45.55 Max Hourly Range: 50.00'
regex.match(str) #should capture 'Min Hourly Rate 33.33 Max Hourly Range: 45.55' (the first match found)
2条答案
按热度按时间ugmeyewa1#
分析
虽然你可以用一个Regexp来实现,但很可能是使用子表达式调用,这将过于复杂,难以调试。您还需要考虑许多其他边缘情况和条件,包括多价验证。与其试图在一个正则表达式中完成所有这些,不如将其划分为更小、更可测试的步骤。虽然这会使代码更长并且(可能)在视觉上不那么优雅,但结果是可以更容易地修改,扩展和测试。
更加面向对象的方法
考虑下面的类,它通过将一些其他域逻辑和验证委托给专门的方法,用一个更简单的正则表达式(请参阅#dynamic_regex_pattern方法,在插值之前只有大约六个原子)为您提供正确的答案。它还使更改用于查找小数的主正则表达式以及它们之间的最大距离变得更容易,因为它们是常量。另一方面,测量它们之间的适当距离的能力变得更加灵活,而无需求助于子表达式,因为类为每个特定的String构建了一个动态模式。
其他兴趣点
这不仅会给予你想要的基本输出,例如。两个十进制数在给定的距离内,但它也会:
1.为任何不包含正好两个十进制值的String对象提供适当的错误。任何其他小数位数的值都被视为错误,因为处理它的业务逻辑未定义。
1.当两个小数点之间的距离大于允许的最大值时,提供错误消息。
1.您可以使用Hash来识别有问题的String对象,只需检查
:error
键的值(如果存在)。1.它区分不同类型的错误,您可以根据需要添加自己的处理程序。
1.它将接受任意数量的String对象作为参数或作为Array。
1.它将原始String存储为Hash键,并将十进制值存储在合理命名的子键中,以便于引用。
1.由于我的解决方案无论如何都要计算小数之间的距离,所以这个解决方案将它们之间的距离存储为一个值作为奖励信息。
下面是上面的String数组示例的输出:
注意事项
首先,这是在Ruby 3.2.2上完成的。输入和输出都经过了合理的严格测试,但在可预见的未来,没有(或将没有)努力使其与其他Ruby兼容。如果它不能在Ruby 2.x、某些即将结束的Ruby或对核心类进行了重大更改的Ruby未来版本上工作,请随时根据需要调整它。
对问题域也做了一些假设。例如,
6
的最大距离表示中间单词的数量,包括未分隔的标点符号,而不是包括开始和/或结束的十进制值。代码足够灵活,可以根据您的需要进行更改。#within_distance?以了解实施细节。在最初的问题中,说你想“捕获2个数字”是模棱两可的,所以我选择将其解释为以一种明显且可检索的方式存储值。如果你的意思不同,可能会有其他更适合你的答案。
无论是最初的例子还是发布的正则表达式都没有处理负值,比如
-14.02
或(你有时会在簿记中看到)(5.30)
。连字符、UTF-8减号等之间也存在差异。除非您对负值的实际字符表示做出更多的假设,否则它可能比您想象的更复杂。所以,我没有解决那些超出范围的问题,尽管我显然选择解决我认为对这个特定问题很重要的其他问题。对于那些对消极价值观有强烈感受的人,即使这不是原始问题的一部分,请随时发布不同的答案。我相信有人会发现它很有用!这个应用程序有几个地方的返回值本质上并不有用。例如,如果调用
pp extractor.extract_results
而不是:你将通过访问器获得#extract_results方法的返回值,而不是 @results Hash的值。目前,这两个是完全不同的,虽然前者做它所说的(它提取的东西),你实际上 * 想要 * 将在所有检查和转换完成后的哈希。
这类事情很容易修复,并且可能是在生产应用程序中实现的好主意,您希望能够轻松地对每个单独方法的返回值进行单元测试,但这超出了我在这里试图演示的范围。
yruzcnhs2#
我假设:
可以匹配正则表达式
Demo
比如说,
正则表达式可以分解如下。