PHP中的模式匹配函数

时间:2011-03-31 18:55:21

标签: php pattern-matching

我正在寻找一个函数,类或函数集合,这将有助于模式匹配字符串的过程,因为我有一个需要大量模式匹配的项目,我想要更容易阅读和维护的东西比原始的preg_replace(或正则表达式)。

我提供了一个伪示例,希望它能帮助您理解我的要求。

$subject = '$2,500 + $550 on-time bonus, paid 50% upfront ($1,250), 50% on delivery ($1,250 + on-time bonus).';
$pattern = '$n,nnn';
pattern_match($subject, $pattern, 0);

将返回“$ 2,500”。

$subject = '$2,500 + $550 on-time bonus, paid 50% upfront ($1,250), 50% on delivery ($1,250 + on-time bonus).';
$pattern = '$n,nnn';
pattern_match($subject, $pattern, 1);

将返回一个值为[$ 2,500],[$ 1,250],[$ 1,250]

的数组

函数 - 我正在尝试编写 - 对数字使用'n',对于小写字母使用'c',对于大写字母alpha使用'C',其中任何非字母数字字符代表自身。

任何帮助都将不胜感激。

5 个答案:

答案 0 :(得分:4)

<?php

// $match_all = false: returns string with first match
// $match_all = true:  returns array of strings with all matches

function pattern_match($subject, $pattern, $match_all = false)
{
  $pattern = preg_quote($pattern, '|');

  $ar_pattern_replaces = array(
      'n' => '[0-9]',
      'c' => '[a-z]',
      'C' => '[A-Z]',
    );

  $pattern = strtr($pattern, $ar_pattern_replaces);

  $pattern = "|".$pattern."|";

  if ($match_all)
  {
    preg_match_all($pattern, $subject, $matches);
  }
  else
  {
    preg_match($pattern, $subject, $matches);
  }

  return $matches[0];
}

$subject = '$2,500 + $550 on-time bonus, paid 50% upfront ($1,250), 50% on delivery ($1,250 + on-time bonus).';
$pattern = '$n,nnn';

$result = pattern_match($subject, $pattern, 0);
var_dump($result);

$result = pattern_match($subject, $pattern, 1);
var_dump($result);

答案 1 :(得分:1)

更新:这是一个不完整的答案,无法阻止多种测试模式。请参阅@Frosty Z的答案以获得更好的解决方案。

<?php
    function pattern_match($s, $p, $c=0) {
        $tokens = array(
            '$' => '\$',
            'n' => '\d{1}',
            'c' => '[a-z]{1}',
            'C' => '[A-Z]{1}'
        );
        $reg = '/' . str_replace(array_keys($tokens), array_values($tokens), $p) . '/';
        if ($c == 0) {
            preg_match($reg, $s, $matches);
        } else {
            preg_match_all($reg, $s, $matches);
        }
        return $matches[0];
    }

    $subject = "$2,500 + $550 on-time bonus, paid 50% upfront ($1,250), 50% on delivery ($1,250 + on-time bonus).";

    $pattern = '$n,nnn';
    print_r(pattern_match($subject, $pattern, 0));
    print_r(pattern_match($subject, $pattern, 1));

    $pattern = 'cc-cccc';
    print_r(pattern_match($subject, $pattern));
    print_r(pattern_match($subject, $pattern, 1));
?>

<强>输出:

$2,500

Array
(
    [0] => $2,500
    [1] => $1,250
    [2] => $1,250
)

on-time

Array
(
    [0] => on-time
    [1] => on-time
)

注意:确保$pattern包含$时使用单引号,否则PHP会尝试将其解析为$variable

答案 2 :(得分:1)

这是没有正则表达式的功能('C'和'c'只识别ascii字符),享受:

function pattern_match($subject, $pattern, $result_as_array) {

    $pattern_len = strlen($pattern);
    if ($pattern_len==0) return false; // error: empty pattern

    // translate $subject with the symboles of the rule ('n', 'c' or 'C')
    $translate = '';
    $subject_len = strlen($subject);
    for ($i=0 ; $i<$subject_len ; $i++) {
        $x = $subject[$i];
        $ord = ord($x);
        if ( ($ord>=48) && ($ord<=57) ) { // between 0 and 9
            $translate .= 'n';
        } elseif ( ($ord>=65) && ($ord<=90) ) { // between A and Z
            $translate .= 'C';
        } elseif ( ($ord>=97) && ($ord<=122) ) { // between a and z
            $translate .= 'c';
        } else {
            $translate .= $x; // othre characters are not translated
        }
    }

    // now search all positions in the translated string

    // single result mode
    if (!$result_as_array) {
        $p = strpos($translate, $pattern);
        if ($p===false) {
            return false;
        } else {
            return substr($subject, $p, $pattern_len);
        }
    }

    // array result mode
    $result = array();
    $p = 0;
    $n = 0;
    while ( ($p<$subject_len)  && (($p=strpos($translate,$pattern,$p))!==false) ) {
        $result[] = substr($subject, $p, $pattern_len);
        $p = $p + $pattern_len;
    }
    return $result;

}

答案 3 :(得分:0)

您正在寻找的功能是preg_match_all,但您需要使用REGEX模式进行模式匹配。

答案 4 :(得分:0)

抱歉,这是正则表达式的问题。我理解你的反对意见,但在这种情况下,没有其他方法可以有效或简单。这是一个非常简单的匹配问题。您可以像jnpcl演示的那样编写自定义包装器,但这只会涉及更多代码和更多潜在的陷阱。更不用说额外的开销了。