1

これはかなり紛らわしいですが、できる限り説明しようと思います...

次のような文字列でいっぱいの MYSQL テーブルがあります。

{3}12{2}3{5}52    

{3}7{2}44    

{3}15{2}2{4}132{5}52{6}22

{3}15{2}3{4}168{5}52

各文字列は、製品オプションとオプション値の組み合わせです。{ } 内の数字はオプションです。たとえば、{3} = 色です。各 { } 番号の直後の番号は、そのオプションの値です (例: 12 = 青)。これらの文字列を解析して情報を正しく配信する方法を知っている PHP コードを既に入手していますが、1 つの例外があります。3,4,2,5,6になります。(現在の順序を受け入れるようにシステムの残りの部分を変更しようとするのは、あまりにも途方もない作業です。) 特定の組み合わせに 5 つのオプションがすべて含まれていなくても問題ありません。たとえば、"{3}7{2}44" は期待される結果。問題は、オプション 2 とオプション 4 を含む組み合わせだけです。オプション 2 とオプション 4 の両方を含む組み合わせ、{4} とそれに対応する値が {2} の前に来て、対応するように順序を入れ替える必要があります。価値。

列を Excel に取り込み、Text to Columns を使用して「{」と「}」の文字で分割し、列の順序を変更しようとしましたが、すべての文字列が同じ数の列を生成するわけではないため、順序は次のようになります。他の方法で台無しになっています (オプション 5 がオプション 2 の前に来るなど)。

また、区切り記号として「}」を使用して、PHP を使用して各文字列を配列に分解することも試しました (後で再ソートできると思いました)。それらを使用できなくする方法。

TL;DR: 上記のような文字列がたくさんあります。「{2}」と「{4}」の両方を含むすべての文字列で、{4} とそれに続く数字が {2} の前に来るように、これらの両方の値の配置を切り替える必要があります。そしてそれに続く数字。言い換えると:

{3}15{2}3{4}168{5}52 

なる必要がある

{3}15{4}168{2}3{5}52

疑似コードで解決策に最も近いのは、次のようなものです。

for each string,
  if "{4}" is present in this string AND "{2}" is present in this string,
     take the "{4}" and every digit that follows it UNTIL you hit another "{" and store that substring as a variable, then remove it from the string.
     then, insert that substring back into the string, at a position starting immediately before the "{2}".

それが何らかの意味を持っていることを願っています...

PHP、Excel、Notepad++、正規表現などでこれを行う方法はありますか? どんな助けでも非常に高く評価されます。

追加するために編集: 私が試した解決策を数人が投稿した後、私のホストが PHP 5.2.17 を実行していることに言及することが重要であることに気付きました。みんなのソリューションに賛成票を投じることができれば(すべてPHPサンドボックスで試し、すべてうまくいきました)、そうしますが、私の担当者は低すぎます。

4

3 に答える 3

1

このようなものはどのように機能しますか。最初の 9 行は、各要素がオプション番号と値の配列である配列に文字列を変換するだけです。Order はアイテムが表示される順序を確立し、最後は位置の順序配列を利用して usort を実行します。

$str = "{3}15{2}2{4}132{5}52{6}22";
$matches = array();
preg_match_all('/\{([0-9]+)\}([0-9]+)/', $str, $matches);

array_shift($matches);
$options = array();
for($x = 0; $x < count($matches[0]); $x++){
    $options[] = array($matches[0][$x], $matches[1][$x]);
}
$order = [3,4,2,5,6];

usort($options, function($a, $b) use ($order) {
   return array_search($a[0], $order) - array_search($b[0], $order); 
});

データを必要な形式に戻すには、次のようにします

$str = "";
foreach($options as $opt){
    $str.="{".$opt[0]."}".$opt[1];
}

ここでのボーナスの 1 つは、新しいオプション タイプを追加するときに、順序を調整することは、オプション番号を $order 配列の正しい位置に挿入するだけの問題であることです。

于 2013-06-06T21:17:42.550 に答える
0

まず第一に、これらのオプションはおそらく別の表にあるはずです。そのような文字列にそれらのものを詰め込む、あらゆる種類の正規化ルールを破っています。

しかし、本当にそれを php で解析したい場合は、次のように文字列を key=>value 配列に分割します。

$options = [];
$pairs = explode('{', $option_string);
foreach($pairs as $pair) {
    list($key,$value) = explode('}', $pair);
    $options[$key] = $value;
}

私はこれがあなたに与えると思います:

$options[3]=15;
$options[2]=3;
$options[4]=168;
$options[5]=52;

別のオプションは、独自のシリアル化の代わりに、何らかの既存のシリアル化 (php の serialize() または json_encode() のいずれか) を使用することです。

$options_string = json_encode($options);
// store $options_string in db

それから

// get $options_string from db
$options = json_decode($options_string);
于 2013-06-06T21:14:29.370 に答える