有没有办法解析这些字符串?

时间:2010-09-11 07:14:23

标签: php

如果有,我当然不会看到它。我们正在对驾驶执照进行磁条读取。数据似乎不一致。驾驶执照应遵循的标准规定了任何一个领域可以拥有的长度限制。我无法解决的部分是如何解析这些数据。

例如,一个字段可能允许13个字符,但只使用8个字符。在这种情况下,将始终有一个插入符号分隔符结束该字符串的该部分。然而,这里是棘手的部分,如果一个字段恰好是13(13个允许的),则没有结束符号分隔符和没有正确的填充。所有数据都是一起运行的。

以下是两个示例字符串。

%CAMISSION HILLSSMITH$JOHN$JIM$JR^1147 SOMESTREET^?
%CALOS ANGELES^DOE$JOHN$CARL^14324 MAIN ST APT 5^?

使用PHP,我该怎么做?我真的很感激这一点。我真的很难过。

4 个答案:

答案 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太熟悉了一种语言而不是才能拥有相同类型的功能。

我希望在某种程度上有所帮助。如果没有其他人回答,我可以尝试创建你需要的正则表达式。

  • gMale