变形字符串到模式

时间:2014-12-18 13:02:01

标签: php regex

我正处理一个问题,即用户(在这种情况下为卡车司机)使用SMS发送有关工作状态的信息。我希望保持简单,因为并非所有用户都拥有智能手机,所以我采用了一些简单的短代码来输入。以下是一些示例及其含义:

  • P#123456-3 (这是为了获取负载123456-3)
  • D#456789-1 (负载下降456789-1)
  • L#345678-9 (负载345678-9将会迟到)

这很简单,但是用户(和卡车司机)就是他们的样子,会以某些不正常的方式关键更新,例如:

  • #D 456789-1
  • D#456789 - 1
  • D#.456789-1这个负载看起来很潮湿,我们需要取消订单

你几乎可以提出十几个其他排列,我抓住并修复那些我能想象到的东西并不难。

我主要使用正则表达式来测试所有想象中的输入" bad"模式然后提取我认为是好的部分,将它们重新组装成正确的顺序。

这是导致我出现问题的新错误,所以我想知道是否有更通用的方法可以传递"模式"和#34;消息"能够做到最好转动"消息的功能#34;进入符合"模式"。

的东西

我的搜索没有发现任何真正适合我尝试做的事情,而且我甚至不确定是否有一个很好的通用方法来做到这一点。我碰巧使用PHP进行此实现,但任何类型的示例都应该有所帮助。你们中有人有方法吗?

4 个答案:

答案 0 :(得分:4)

如果用户的软件出现问题,请修复软件,而不是用户!

问题出现是因为您的格式看起来不必要复杂。为什么你首先需要哈希?如何将其简化为以下内容:

 operation-code maybe-space load-number maybe-space and comment

操作代码分配给不同的电话键,因此JKL表示相同的内容。加载号码也可以作为数字和字母发送,例如agja表示2452。用户很难使用这种格式出错。

这里有一些代码来说明这种方法:

function parse($msg) {

    $codes = array(
        3 => 'DROP',
        5 => 'LOAD',
        // etc
    );

    preg_match('~(\S)\s*(\S+)(\s+.+)?~', $msg, $m);
    if(!$m)
        return null; // cannot parse

    $a = '.,"?!abcdefghijklmnopqrstuvwxyz';
    $d = '1111122233344455566677777888999';

    return array(
        'opcode'  => $codes[strtr($m[1], $a, $d)],
        'load'    => intval(strtr($m[2], $a, $d)),
        'comment' => isset($m[3]) ? trim($m[3]) : ''
    );
}

print_r(parse(' j ww03 This load looks wet to me'));
//[opcode] => LOAD
//[load] => 9903
//[comment] => This load looks wet to me

print_r(parse('dxx0123'));
//[opcode] => DROP
//[load] => 990123
//[comment] => 

答案 1 :(得分:3)

首先,删除不应存在的内容:

$str = preg_replace('/[^PDL\d-]/i', '', $str);

这为您提供了以下标准化结果:

D456789-1
D456789-1
D456789-1ldlddld

然后,尝试匹配您想要的数据:

if (preg_match('/^([PDL])(\d+-\d)/i', $str, $match)) {
    $code = $match[1];
    $load = $match[2];
} else {
    // uh oh, something wrong with the format!
}

答案 2 :(得分:3)

尝试这样的事情:

function parse($input) {
    // Clean up your input: 'D#.456789 - 1 foo bar' to 'D 456789 1 foo far'
    $clean = trim(preg_replace('/\W+/', ' ', $input));
    // Take first 3 words.
    list($status, $loadId1, $loadId2) = explode(' ', $clean);
    // Glue back your load ID to '456789-1'
    $loadId = $loadId1 . '-' . $loadId2;
    return compact('status', 'loadId');
}

示例:

$inputs = array(
    'P#123456-3',
    '#D 456789-1',
    'D# 456789 - 1',
    'D#.456789-1 This load looks wet to me do weneed to cancelthis order',
);
echo '<pre>';
foreach ($inputs as $s) {
    print_r(parse($s));
}

输出:

Array
(
    [status] => P
    [loadId] => 123456-3
)
Array
(
    [status] => D
    [loadId] => 456789-1
)
Array
(
    [status] => D
    [loadId] => 456789-1
)
Array
(
    [status] => D
    [loadId] => 456789-1
)

答案 3 :(得分:2)

这样的东西
/^[#\s]*([PDL])[#\s]*(\d+[\s-]+\d)/

或者更放松,

/^[^\d]*([PDL])[^\d]*(\d+)[^\d]+(\d)/

会得到你想要的东西。但是我更喜欢HamZa的评论作为解决方案:把它扔回去告诉他们让他们一起行动:))