我是正则表达的新手。 我想拼出小于10的数字,这些数字不是测量单位(cm,mm,m等)。 我试过了..
<?php
//spell out the numbers less than 10 which are not units of time
$match="5 feet";
if(preg_match('/(\d+)\s((?i)(?:j|kg|mm|cm|km|cu|ft|nm|khz|mhz|w|kw|sq|gb|kb|ghz|thz/',$match))
{
echo $match;
}
else
{
$replacement='$1 $2';
$x=preg_replace('/(\d+)\s((?i)(?:j|kg|mm|cm|km|cu|ft|nm|khz|mhz|w|kw|sq|gb|kb|ghz|thz))/',$replacement,$match);
}
echo convert($x);
function convert($string)
{
$spell = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
$num = range(0, 9);
return str_replace($num, $spell, $string);
}
?>
它适用于指定的单位。有更好的方法。我还想拼出所有单位的名称。
示例输出:
Input: 5 cm 5 mm
Output: 5 cm 5 mm
Input: 5 car 5 mm
Output: five car 5 mm
答案 0 :(得分:0)
创建一个允许的单位数组,然后使用您的模式。
尝试类似
的内容$units = array("kg", "mm", "cm", "km");
preg_match(....);
答案 1 :(得分:0)
正如ling.s所说,数组是正确的方法,但您可以使用preg_replace_callback
来大大简化代码。要做到这一点,你需要搜索不的数字,然后进行测量,这使用'(?!...)'这样:
(/d+)(?!\s*(?:mm|kg))
匹配任何未跟随'mm'的数字,'?:'告诉系统不要将mm / kg作为匹配返回,即使它在括号中。如果你有一组单位,很容易得到implode($units, "|")
的内部reg exp部分。您可以将所有这些放在一起,以获得仅匹配未跟踪测量的数字的正则表达式。
现在你可以稍微改变你的转换函数,使其兼容preg_replace_callback
的回调,所有需要是接受第一个元素是完全匹配的数组:
function convert($matches)
{
$spell = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
$num = range(0, 9);
return str_replace($num, $spell, $matches[0]);
}
这将为每个匹配调用,并将该匹配替换为返回的字符串,其余代码为:
function fix_numbers($match) {
$units = array("j","kg","mm","cm","km","cu","ft");
// Lookahead for unit match
$regex = "/(\d+)(?!\s*(?:".implode($units, "|")."))/";
return preg_replace_callback($regex, "convert", $match);
}
测试代码:
echo fix_numbers("5 feet 6 mm 3 trees") . "\n";
echo fix_numbers("5 cm 5 mm") . "\n";
echo fix_numbers("5 car 5 mm") . "\n";
输出:
five feet 6 mm three trees
5 cm 5 mm
five car 5 mm
现在,仍有一个潜在的问题 - 对于像'cu'这样的单位,它也会匹配像'cube'这样的文字,所以你可能想在单位之后搜索一个空格。但这使得最后一场比赛变得复杂。这实际上取决于您的输入。
此外,您的转换功能有限,如果您想用更全功能的版本替换它,还有很多其他选项(例如:http://www.karlrixon.co.uk/writing/convert-numbers-to-words-with-php/)