2017-06-17 6 views
0

私はこのパターンを持っている4桁の番号のパターンマッチを作るためにPHPでpreg_match()を使用しようとしている:お互いに重複した番号を検索するにはどうすればよいですか?

0033 
1155 
2277 

は、基本的には最初の2桁が同じであり、最後の2桁は同じですが、すべての4桁が同じではありません。

preg_match()でも正しい機能を使用できますか?または、私はそれらを分割し、そのように一致させるべきですか?

+0

このために正規表現を使用しようとすると非常に困難です。多分それはできますが、私は結果がどのように見えるか想像できません。 2つのグループの繰り返しの数字が異なる必要があるため、書くのは本当に難しい正規表現です。あなたは、他のいくつかのソリューションを使う方がずっと優れています。あなたがその要件を省略することができれば、 '(\ d)\ 1(\ d)\ 2'がおそらく動作します。 – Joel

+0

@Joel \ 1と\ 2はどういう意味ですか? 113022という数字があれば(\ d)\ 1 [30] +(\ d)\ 2に一致します。どうして?私は\ 1と\ 2が数字の位置であると思った... – John

+0

これはグループ参照の取得です。これにより、キャプチャグループを2倍にするか、3倍にするか、または任意のものを指定することができます。 '^(\ d)\ 1(\ d)\ 2 $'境界を追加することで、そのソートの入力を受け付けないようにすることができます。それはあなたの入力を4桁の「単語」に制限します。 – Joel

答えて

1

あなたは比較コールバックでarray_filterのようなものを使用することができます:あなたはまた、クロージャを使用してこれを行うことが

function compare($number) { 
    // Compare first 2 numbers 
    if (intval($number[0]) !== intval($number[1])) { 
     return false; 
    } 

    // Compare last 2 numbers 
    if (intval($number[2]) !== intval($number[3])) { 
     return false; 
    } 

    // Make sure first and last numbers aren't the same 
    if (intval($number[0]) === intval($number[3])) { 
     return false; 
    } 

    return true; 
} 

$data = array_filter($data, 'compare'); 

:ここ

$data = array_filter($data, function($number) { 
    return intval($number[0]) === intval($number[1]) && intval($number[2]) === intval($number[3]) && intval($number[0]) !== intval($number[3]); 
}); 

例:http://ideone.com/0VwJz8

+0

この答えでは、各文字を数字にする必要はなく、文字列オフセットを使って同じ比較を行うことができるので、 'str_split()'は必要ありません。 3つの別々のif文を使用することは、膨大なコードを意味し、匿名の 'array_filter()'メソッドのような単一の条件セットを使用する方が良いでしょう。 Casimirのパターン/メソッドは、必要に応じて実行され、他の正規表現パターンと組み合わせて使用​​して、より多くのデータを1つのステップで抽出することができます。 – mickmackusa

+0

@mickmackusaあなたは 'str_split'を必要としないのが正しいでしょうが、もっとコードであっても、より大きなデータセットで悪化する' preg_match'を使うよりも、一回の実行でより効率的です:http://ideone.com/ SZ7sRW/http://ideone.com/g7Txf8。私は方法でそれを打ち破ったので、OPはそれぞれの声明が何をしているかを見ることができた。文字列の制限を回避するには、intにキャストするかsprintfを使用して処理してください。これは、各文字がゼロにキャストされるため、文字列が3番目の条件に失敗する原因になります。 – sjdaws

+0

今度は、各繰り返しで3回の比較と6回の関数呼び出しのように見えます。私は単一の 'preg_match()'呼び出しを好むでしょう。 – mickmackusa

3

をこの種類を検索しますあなたが使用できるテキストの数字の数:

preg_match('~\b(\d)\1(?!\1)(\d)\2\b~', $str, $m) 

(またはpreg_match_allとあなたがそれらのすべてをしたい場合)

詳細:

~  # pattern delimiter 
\b  # word boundary (to be sure that 1122 isn't a part of 901122) 
(\d)  # capture the first digit in group 1 
\1  # back-reference to the group 1 
(?!\1) # negative lookahead: check if the reference doesn't follow 
(\d)  # 
\2  # 
\b  # word boundary (to be sure that 1122 isn't a part of 112234) 
~  # 

あなたは、文字列全体が数字であるかどうかを確認したい場合は、代わりに文字列制限アンカーを使用単語境界:

~\A(\d)\1(?!\1)(\d)\2\z~ 
+0

これはそれのように見えます。私が新しい質問を作成する必要がある場合はDunnoですが、あなたのコードをそこに置くと、自動的にこれを使ってどのようなパターンにも一致する方法がありますか? XXは同じ数字を意味するので、YYはXXと同じではなく、0と同じであることを意味し、0を検索するだけです。パターンがXXX0の場合は5550が一致します。渡されるパターンに一致するように動的に一致するコードを作成するコードを記述する方法について考えてみませんか? – John

+0

いずれにしても私はあなたの答えを受け入れるでしょう。私が上記のパターンと一致するためにもう一度それを利用できるかどうかを見たいだけです。 – John

+0

@Johnこれを使用できます:http://sandbox.onlinephpfunctions.com/code/f1589e5e89b0c810662851a978f2696f3632610e – mickmackusa

関連する問題