如何解决regex匹配不可约分数
| 如何将正则表达式与不可约分数匹配? 例如23 / 25、3 / 4、5 / 2、100 / 101等。 首先,我不了解正则表达式中的gcd-算法实现。 为所有回答“例如您使用的工具错误”的人更新: 是的,伙计们,我正在意识到正则表达式通常用于什么目的。没关系。但是这个问题很奇怪,这是它的全部要点。 更新2:的想法是找到一个正则表达式,可以在以下情况下有所帮助:$> echo \"1/2\" | grep -P regex
1/2
$> echo \"2/4\" | grep -P regex
因此,正则表达式只能是一个字符串,而不使用任何脚本和变量。只有正则表达式。
实际上,我已经知道一些正则表达式,它们与一元数系统中写的可约分数匹配。
$> echo \"11/1111\" | grep -P \'^1/1+$|(11+)+\\1+/\\1+$\'
11/1111
因此,事情是在正则表达式中从十进制转换为一进制数,但我不知道如何。
解决方法
更新
由于发布者请求的单个正则表达式与\“ 36/270 \”之类的字符串匹配,但是说它的可读性并不重要,因此该正则表达式为:
my $reducible_rx = qr{^(\\d+)/(\\d+)$(?(?{(1x$1.\"/\".1x$2)=~m{^(?|1+/(1)|(11+)\\1*/\\1+)$}})|^)};
但是,如果像我一样,您认为难以接受的正则表达式是绝对不能接受的,那么您将更清楚地写为:
my $reducible_rx = qr{
# first match a fraction:
^ ( \\d+ ) / ( \\d+ ) $
# now for the hard part:
(?(?{ ( 1 x $1 . \"/\" . 1 x $2 ) =~ m{
^
(?| 1+ / (1) # trivial case: GCD=1
| (11+) \\1* / \\1+ # find the GCD
)
$
}x
})
# more portable version of (*PASS)
| ^ # more portable version of (*FAIL)
)
}x;
通过将与一进制版本匹配的版本从与十进制版本匹配的版本中分离出来,可以提高可维护性:
# this one assumes unary notation
my $unary_rx = qr{
^
(?| 1+ / (1)
| (11+) \\1* / \\1+
)
$
}x;
# this one assumes decimal notation and converts internally
my $decimal_rx = qr{
# first match a fraction:
^ ( \\d+ ) / ( \\d+ ) $
# now for the hard part:
(?(?{( 1 x $1 . \"/\" . 1 x $2 ) =~ $unary_rx})
# more portable version of (*PASS)
| ^ # more portable version of (*FAIL)
)
}x;
将其分成两个命名的正则表达式不是很容易吗?现在,ѭ5与as6相同,但是一元版本是它自己的东西。我就是这么做的,但是原始的海报只需要一个正则表达式,因此您必须在上面第一次插入的时候对嵌套的正则表达式进行插值。
无论哪种方式,都可以使用以下方法插入下面的测试工具:
if ($frac =~ $reducible_rx) {
cmp_ok($frac,\"ne\",reduce($i,$j),\"$i/$j is $test\");
} else {
cmp_ok($frac,\"eq\",\"$i/$j is $test\");
}
您会发现它是通过所有测试的正确正则表达式,而且使用单个正则表达式也是如此。因此,现在已经通过了原始问题的所有要求,我声明Qᴜᴏᴅsᴅᴇᴍᴏɴ:“退出,已完成。”版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。