4

PHPマニュアル、Stackoverflow、およびいくつかのフォーラムを検索しましたが、いくつかのPHPロジックに困惑しています。疲れたばかりかもしれませんが、誰かの助けや指示をいただければ幸いです。

私はPHP文字列を持っています、例えば:

 $string = 'cats cat1 cat2 cat3 dogs dog1 dog2 monkey creatures monkey_creature1 monkey_creature2 monkey_creature3';

最終的には、最終的な出力を次のようにするのが理想的ですが、今のところ配列を取得するだけで十分です。

 <h2>cats</h2>
 <ul>
     <li>cat1</li>
     <li>cat2</li>
     <li>cat3</li>
 </ul>

 <h2>dogs</h2>
 <ul>
     <li>dog1</li>
     <li>dog2</li>
 </ul>

 <h2>monkey creatures</h2>
 <ul>
     <li>monkey_creature1</li>
     <li>monkey_creature2</li>
     <li>monkey_creature3</li>
 </ul>

ただし、落とし穴がありますが、文字列がわずかに異なる場合があります。

 $string = 'cats cat1 cat2 cat3 cat4 cat5 cats6 dogs dogs1 dogs2 monkey creatures monkey_creature1 lemurs lemur1 lemur2 lemur3';

とにかく、これはStackoverflowに関する私の最初の質問であり、すべてのヘルプ担当者に事前に感謝します!

編集:私はいくつかの特定の制限の下で作業しており、文字列の前のコードを変更することはできません。私は高度にすべての親を知っています(「猫」、「犬」、「キツネザル」、「猿の生き物(スペース付き)」

4

5 に答える 5

4

最初のキーワードが複数形でない限り、「キーワード」の間にスペースがあるかどうかに関係なく機能する回答を設計しました:)

以下はコードです。お気軽にチェックしてください。テキストでできることは本当に美しいです:)

<?
$string = 'cats cat1 cat2 cat3 dogs dog1 dog2 monkey creatures monkey_creature1 monkey_creature2 monkey_creature3';

$current_prefix = '';
$potential_prefix_elements = array();

$word_mapping = array();

foreach(split(" ", $string) as $substring) {
    if(strlen($current_prefix)) {
        // Check to see if the current substring, starts with the prefix
        if(strrpos($substring, $current_prefix) === 0)
            $word_mapping[$current_prefix . 's'][] = $substring;
        else
            $current_prefix = '';
    }

    if(!strlen($current_prefix)) {
        if(preg_match("/(?P<new_prefix>.+)s$/", $substring, $matches)) {
            $potential_prefix_elements[] = $matches['new_prefix'];

            // Add an 's' to make the keys plural
            $current_prefix = join("_", $potential_prefix_elements);

            // Initialize an array for the current word mapping
            $word_mapping[$current_prefix . 's'] = array();

            // Clear the potential prefix elements
            $potential_prefix_elements = array();
        } else {
            $potential_prefix_elements[] = $substring;
        }
    }
}

print_r($word_mapping);

これが出力です。配列として提供したので、ul / li階層を簡単に構築できます:)

Array
(
    [cats] => Array
        (
            [0] => cat1
            [1] => cat2
            [2] => cat3
        )

    [dogs] => Array
        (
            [0] => dog1
            [1] => dog2
        )

    [monkey_creatures] => Array
        (
            [0] => monkey_creature1
            [1] => monkey_creature2
            [2] => monkey_creature3
        )

)
于 2012-05-04T03:32:52.760 に答える
2

preg_match_allおそらく関数を使用し、正規表現を使用したいと思うでしょう。そうすれば、ループを使用する必要はありません。

$matches = array();
$string = 'cats cat1 cat2 cat3 dogs dog1 dog2 monkey creatures monkey_creature1 monkey_creature2 monkey_creature3'
preg_match_all('/((?:[a-z]+ )*?[a-z]+s) ((?:[a-z_]+[0-9] ?)+)*/i', $string, $matches);

// $matches now contains multidemensional array with 3 elements, indices
// 1 and 2 contain the animal name and list of those animals, respectively
$animals = array_combine($matches[1], $matches[2]);
$animals = array_map(function($value) {
    return explode(' ', trim($value));
}, $animals);
print_r($animals);

出力:

Array
(
    [cats] => Array
        (
            [0] => cat1
            [1] => cat2
            [2] => cat3
        )

    [dogs] => Array
        (
            [0] => dog1
            [1] => dog2
        )

    [monkey creatures] => Array
        (
            [0] => monkey_creature1
            [1] => monkey_creature2
            [2] => monkey_creature3
        )

)
于 2012-05-04T03:55:58.363 に答える
1

文字列としての2番目の例:

<?php

$parents = array('cats', 'dogs', 'monkey creatures', 'lemurs');
$result = array();

$dataString = 'cats cat1 cat2 cat3 cat4 cat5 cats6 dogs dogs1 dogs2 monkey creatures monkey_creature1 lemurs lemur1 lemur2 lemur3';
foreach ($parents as $parent) {
  // Consider group only if it is present in the data string
  if (strpos($dataString, $parent) !== false) {
    $result[$parent] = array();
  }
}
$parts = explode(' ', $dataString);
foreach (array_keys($result) as $group) {
  $normalizedGroup = str_replace(' ', '_', $group);
  foreach ($parts as $part) {
    if (preg_match("/^$normalizedGroup?\d+$/", $part)) {
      $result[$group][] = $part;
    }
  }
}
print_r($result);

出力:

Array
(
    [cats] => Array
        (
            [0] => cat1
            [1] => cat2
            [2] => cat3
            [3] => cat4
            [4] => cat5
            [5] => cats6
        )

    [dogs] => Array
        (
            [0] => dogs1
            [1] => dogs2
        )

    [monkey creatures] => Array
        (
            [0] => monkey_creature1
        )

    [lemurs] => Array
        (
            [0] => lemur1
            [1] => lemur2
            [2] => lemur3
        )

)
于 2012-05-04T03:42:44.900 に答える
1

これが私の$0.50です

<?php
$parents = array('cats', 'dogs', 'lemurs', 'monkey creatures');

// Convert all spaces to underscores in parents
$cleaned_parents = array();
foreach ($parents as $parent)
{
        $cleaned_parents[] = str_replace(' ', '_', $parent);
}

$input = 'cats cat1 cat2 cat3 dogs dog1 dog2 monkey creatures monkey_creature1 monkey_creature2 monkey_creature3';

// Change all parents to the "cleaned" versions with underscores
$input = str_replace($parents, $cleaned_parents, $input);

// Make an array of all tokens in the input string
$tokens = explode(' ', $input);
$result = array();

// Loop through all the tokens
$currentParent = null; // Keep track of current parent
foreach ($tokens as $token)
{
    // Is this a parent?
    if (in_array($token, $cleaned_parents))
    {
        // Create the parent in the $result array
        $currentParent = $token;
        $result[$currentParent] = array();
    }
    elseif ($currentParent != null)
    {
        // Add as child to the current parent
        $result[$currentParent][] = $token;
    }
}

print_r($result);

出力:

Array
(
    [cats] => Array
        (
            [0] => cat1
            [1] => cat2
            [2] => cat3
        )

    [dogs] => Array
        (
            [0] => dog1
            [1] => dog2
        )

    [monkey_creatures] => Array
        (
            [0] => monkey_creature1
            [1] => monkey_creature2
            [2] => monkey_creature3
        )

)
于 2012-05-04T03:47:53.857 に答える
1

私はベストアンサーを提出することができないと考えたので、最少行数で実行することにしました。(冗談です、非常に汚いコードで申し訳ありません)

$string = 'cats cat1 cat2 cat3 cat4 cat5 cats6 dogs dogs1 dogs2 monkey creatures monkey_creature1 lemurs lemur1 lemur2 lemur3';
$categories = array( 'cats', 'dogs', 'monkey creatures', 'lemurs' );

for( $i=0; $i<count( $categories ); $i++ ) $parts[] = @explode( ' ', strstr( $string, $categories[$i] ) );
for( $i=0; $i<count( $parts ); $i++ ) $groups[] = ($i<count($parts)-1) ? array_diff( $parts[$i], $parts[$i+1] ) : $parts[$i];
for( $i=0; $i<count( $groups ); $i++ ) for( $j=0; $j<count( $groups[$i] ); $j++ ) if( ! is_numeric( substr( $groups[$i][$j], -1 ) ) ) unset($groups[$i][$j]);

print_r( $groups );

私の方法は、要素には数字の接尾辞が必要であるという事実に依存していることに気付くかもしれません。これは実際にはナンセンスですが、扱っている入力としてはナンセンスです。

私の出力は次のとおりです。

Array
(
    [0] => Array
        (
            [1] => cat1
            [2] => cat2
            [3] => cat3
            [4] => cat4
            [5] => cat5
            [6] => cats6
        )

    [1] => Array
        (
            [1] => dogs1
            [2] => dogs2
        )

    [2] => Array
        (
            [2] => monkey_creature1
        )

    [3] => Array
        (
            [1] => lemur1
            [2] => lemur2
            [3] => lemur3
        )

)
于 2012-05-04T03:59:50.223 に答える