2011-06-28 7 views
1

私はこのようなものを探しています:How to generate a regular expression at runtime to match a numeric rangeが、PHPで書かれています。番号範囲に一致するPHP正規表現ジェネレータはどこにありますか?

+0

基本的なJavaとPHPの文法THAT非類似のものではなく、正規表現の構文はかなりあまりにも標準化されています。他の答えの正規表現を自分で翻訳しようとしませんか? –

+0

String.format(n == m?n == 1 "": "{%d}": "{%d、%d}"、n、m) – Ivan

答えて

3

コメントはコードブロックにとっては恐ろしいので、ここで質問してください。私はそのような声明を直接翻訳することはできません。それはほとんど読めません。それは次のように離れて選択する方がはるかに簡単です:

if ($n == $m) { // max/min ranges are the same, so just look for that number of characters 
    $format = "\{$n\}"; // {n} 
} elseif ($n == 1) { // min range is 1, so use the max 
    $format = "\{1,$m\}"; // {1,m} 
} else { // arbitary n->m range 
    $format = "\{$n,$m\}"; // {n,m} 
} 

それは三元としてPHPで行うことができ、それはしかし、デバッグが不可能/同じように判読不能です:

$format = ($n == $m) ? "\{$n\}" : (($n == 1) ? "\{1,$m\}" : "\{$n,$m\}"); 
0

私は、これは動作するはずだと思います。

class NumericRangeRegexGenerator { 

private function baseRange($num,$up, $leading1) { 

    $c = $num[0]; 
    $low = $up ? $c : ($leading1 ? '1' : '0'); 
    $high = $up ? '9': $c; 

    if (strlen($num) == 1) 
     return $this->charClass($low, $high); 

    $re = $c . "(" . $this->baseRange(substr($num,1), $up, false) . ")"; 

    if ($up) $low++; else $high--; 

    if ($low <= $high) 
     $re .= "|" . $this->charClass($low, $high) . $this->nDigits(strlen($num) - 1); 

    return $re; 
} 

private function charClass($b, $e) { 
    //String.format(b==e ? "%c" : e-b>1 ? "[%c-%c]" : "[%c%c]", b, e); (in java) 
    if ($b == $e) { 
     $format = $b; 
    } elseif ($e-$b>1) { 
     $format = '['.$b.'-'.$e.']'; 
    } else { 
     $format = '['.$b.$e.']'; 
    } 
    return $format; 
} 

private function nDigits($n, $m=null) { 
    //String.format(n==m ? n==1 ? "":"{%d}":"{%d,%d}", n, m) (in java) 

      if($m===null){ 
       nDigits($n, $n); 
      } 

    if ($n == $m) { // max/min ranges are the same, so just look for that number of characters 
     $format = "\{$n\}"; // {n} 
    } elseif ($n == 1) { // min range is 1, so use the max 
     $format = "\{1,$m\}"; // {1,m} 
    } else { // arbitary n->m range 
     $format = "\{$n,$m\}"; // {n,m} 
    } 
    return "[0-9]" . $format; 
} 

private function eqLengths($from, $to) { 

    $fc = $from[0]; 
      $tc = $to[0]; 

    if (strlen($from) == 1 && strlen($to) == 1) 
     return $this->charClass($fc, $tc); 

    if ($fc == $tc) 
     return $fc . "(".$this->rangeRegex(substr($from,1), substr($to,1)).")"; 

    $re = $fc . "(" . $this->baseRange(substr($from,1), true, false) . ")|" 
       . $tc . "(" . $this->baseRange(substr($to,1), false, false) . ")"; 

    if (++$fc <= --$tc) 
     $re .= "|" . $this->charClass($fc, $tc) . $this->nDigits(strlen($from) - 1); 

    return $re; 
}  

private function nonEqLengths($from, $to) { 
    $re = $this->baseRange($from,true,false) . "|" . $this->baseRange($to,false,true); 
    if (strlen($to) - strlen($from) > 1) 
     $re .= "|[1-9]" . $this->nDigits(strlen($from), strlen($to) - 2); 
    return $re; 
} 

public function rangeRegex($n, $m) { 
    return strlen($n) == strlen($m) ? $this->eqLengths($n, $m) : $this->nonEqLengths($n, $m); 
} 

}

+0

このコードは実行されますしかし、それは私に望ましい結果を与えていません。 $ regexer-> rangeRegex(123,321)に対して;私は(2([31]))を取得しますが、これは正しくありません。 – Ivan

関連する問題