我正在从CSV文件中读取数据,该文件包含附加了单位的数量。我需要将值与单位分开。
我读入的值可以是毫伏 mV 或仅伏特 V 的单位。如果$splitter[0]
中的字符串为1.987mV
。我想将其分为两个值1.987
和mV
。
$splitter[0] =~ /(.*)([mV])/;
print "$1 -- $2\n";
此输出
1.987m -- V
如果$splitter[0]
中的单位 V ,那么它似乎正在运作。
有谁知道为什么我没有拿起 m ?
答案 0 :(得分:2)
您character class之后没有重复,因此您要求该角色类中的任何内容进行单一匹配,即m
或V
。不过有很多方法可以给这只猫上皮:
/^([\d.]+)(\D+)$/
/^([\d.]+)(\w+)$/
/^([^A-Za-z]+)(\w+)$/
/^([^A-Za-z]+)([A-Za-z]+)$/
/(.*)(mV|m)/
/(.*)(m?V)/
上面的一些解决方案更多"正确"相对于其它的。
此外,您通常希望尝试使用正则表达式尽可能限制并完全符合您的意思。如果你能提供帮助,请尽量远离.
,而是选择更具体的模式。
答案 1 :(得分:0)
正如您所读到的,您的代码只在字符串末尾找到 V 的一个原因是因为您的字符类只匹配一个字符。 [mV]
匹配单个小 m 或单个大写 V 。要匹配多个字符,您需要一个与[mV]+
匹配的量词,它将匹配一个或多个字符,例如 m 或 V 或 mVm 或 mV 等。
另一个原因是你之前有一个贪心匹配。 .*
将匹配任何字符的零个或多个,因此即使您修改单位上的量词并写入/(.*)([mV]+)/
,您仍然会得到1.9876m
和V
因为点是很高兴匹配 m ,让[mv]+
只匹配 V
假设数量是数字,由十进制数字和可能的小数点组成,单位总是字母(包括 micro 的希腊mu μ)然后你可以像这样分割价值
use utf8;
use strict;
use warnings 'all';
use v5.10;
use open qw/ :std :encoding(UTF-8) /;
my @splitter = qw/ 1.987mV 442.0μH /;
for ( @splitter ) {
my ($val, $units) = / ([0-9.]+) (\p{Letter}+) /x;
say "$val ~ $units";
}
1.987 ~ mV
442.0 ~ μH