如果有,我当然不会看到它。我们正在对驾驶执照进行磁条读取。数据似乎不一致。驾驶执照应遵循的标准规定了任何一个领域可以拥有的长度限制。我无法解决的部分是如何解析这些数据。
例如,一个字段可能允许13个字符,但只使用8个字符。在这种情况下,将始终有一个插入符号分隔符结束该字符串的该部分。然而,这里是棘手的部分,如果一个字段恰好是13(13个允许的),则没有结束符号分隔符和没有正确的填充。所有数据都是一起运行的。
以下是两个示例字符串。
%CAMISSION HILLSSMITH$JOHN$JIM$JR^1147 SOMESTREET^?
%CALOS ANGELES^DOE$JOHN$CARL^14324 MAIN ST APT 5^?
使用PHP,我该怎么做?我真的很感激这一点。我真的很难过。
答案 0 :(得分:5)
好的,我们走了。我使用x
标志使正则表达式更具可读性并能够对其进行评论。
根据发布的@EboMike规范,每个字段都有一个最大长度,如果短于该长度则由^
终止。该名称是一个复合字段,使用$
作为姓氏,名字,中间名和后缀之间的分隔符。地址也是如此,如果地址有多行,则使用$
。
$licenses = array(
'%CAMISSION HILLSSMITH$JOHN$JIM$JR^1147 SOMESTREET^?',
'%CALOS ANGELES^DOE$JOHN$CARL^14324 MAIN ST APT 5^?'
);
foreach ($licenses as $license) {
preg_match(
'@
^%
(.{2}) # State, 2 chars
([^^]{0,12}.) # City, 13 chars, delimited by ^
([^^]{0,34}.) # Name, 35 chars, delimited by ^
([^^]{0,28}.) # Address, 29 chars, delimited by ^
\?$
@x',
$license,
$fields
);
$state = $fields[1];
$city = rtrim($fields[2], '^');
$name = explode('$', rtrim($fields[3], '^'));
$address = explode('$', rtrim($fields[4], '^'));
echo "$license\n";
echo "STATE: "; print_r($state); echo "\n";
echo "CITY: "; print_r($city); echo "\n";
echo "NAME: "; print_r($name);
echo "ADDRESS: "; print_r($address);
echo "\n";
}
输出:
CAMISSION HILLSSMITH$JOHN$JIM$JR^1147 SOMESTREET^
STATE: CA
CITY: MISSION HILLS
NAME: Array
(
[0] => SMITH
[1] => JOHN
[2] => JIM
[3] => JR
)
ADDRESS: Array
(
[0] => 1147 SOMESTREET
)
CALOS ANGELES^DOE$JOHN$CARL^14324 MAIN ST APT 5^
STATE: CA
CITY: LOS ANGELES
NAME: Array
(
[0] => DOE
[1] => JOHN
[2] => CARL
)
ADDRESS: Array
(
[0] => 14324 MAIN ST APT 5
)
答案 1 :(得分:3)
几小时前你没有问过这个问题吗?有人发布了一个正则表达式,用于处理分隔字符串的情况,这些字符串分隔或在此处运行13个字符:Help with a delimited string
这不起作用吗?
编辑:格式在此解释:http://en.wikipedia.org/wiki/Magnetic_stripe_card#United_States_driver.27s_licenses
对于城市,它说“场分隔符 - 一个字符(通常为'^')(如果城市达到最大长度则不存在)”。再说一次,一个简单的正则表达式可以在这里创造奇迹。请参阅示例,您可以调整它以匹配此处条目中详细说明的格式。
编辑:好的,我会试一试。$str = "%CAMISSION HILLSSMITH$JOHN$JIM$JR^1147 SOMESTREET^?";
preg_match("/%(..)".
"([^\^]{1,13})\^?".
"([^\\\$]+)\\\$".
"([^\\\$]+)\\\$/",
$str, $m);
$State = $m[1];
$City = $m[2];
$LastName = $m[3];
$FirstName = $m[4];
正如hwo的一个例子,你可以去做它。
基本上,([^\^]{1,13})
意味着它会尝试最多13个不是'^'字符的字符。一旦完成,它将通过\^?
消耗'^'字符本身。
答案 2 :(得分:2)
从左到右工作,一次处理一个字段。
剥离前导%:
CAMISSION HILLSSMITH$JOHN$JIM$JR^1147 SOMESTREET^?
取前15个字符(第一个字段最多15个字符,对吧?):
CAMISSION HILLS
不包含插入符号 - 这是我们的第一个字段 - 下一个字段从第16个字符开始:
SMITH$JOHN$JIM$JR^1147 SOMESTREET^?
(R1)
我不知道最大的len。这个领域 - 让我们假设它是20.拿前20个字符:
SMITH$JOHN$JIM$JR^11
包含插入符 - 所以我们>这里有1个字段。将字符带到插入符号:
SMITH$JOHN$JIM$JR
......这是我们的下一个领域。现在从上面的(R1)抓取字符串(从prev字段的长度+2)开始(+2跳过^)
1147 SOMESTREET^?
等
答案 3 :(得分:0)
如果这是java,我会用正则表达式解决这个问题。我知道PHP中一定有一些吗?
您提到的所有限制都可以转换为REGEX。
例如:
X{n,m}? X, at least n but not more than m times
可以用于:
[^%\$\^]{1,13}[%\$\^]
其中的内容为“1-13个任何字符不等于%,$或^后跟其中一个相同分隔符的实例”
当我写正则表达式时,我经常会回到Java's great doc page。你也可以做一些巧妙的技巧,例如提取特定的匹配部分并提取特定的单词。再一次,我对java更熟悉,但PHP太熟悉了一种语言而不是才能拥有相同类型的功能。
我希望在某种程度上有所帮助。如果没有其他人回答,我可以尝试创建你需要的正则表达式。