CodeX
CodeX

Reputation: 313

Create a simple PHP Array from this text

I have this lovely chunk of text found inside an XML element and want to convert it into a simple array, the XML is from wikia.com.

The array would be something like this:

card name => [Martial] Ares, character name => Ares, release_date => May 1 2013 and so on..

I've tried all sorts of imploding and exploding variations but no luck.. This one has got me stumped..

|card name=[Martial] Ares
|character name=Ares
|release_date=May 1 2013
|image 1=MartialAres5.jpg
|rarity 1=Super Special Rare
|pwr req 1=28
|sale price 1=94200
|max card lv 1=60
|max mastery lv 1=40
|quote 1=Ares prefers weapons that were used during the age of Greek myth: sword, axe, and spear.  But he can use any weapon expertly, and turn most ordinary objects into lethal weapons.
|base atk 1=2440
|base def 1=2650
|max atk 1=7015
|max def 1=7613
|mastery bonus atk 1=915
|mastery bonus def 1=993
|image 2=MartialAres6.jpg
|rarity 2=Ultimate Rare
|sale price 2=188400
|max mastery lv 2=200
|quote 2=Next time I see Hercules, We're going to have a steel conversation. It's about time for him to answer for massacring my Stymphalian Birds.
|max atk 2=9822
|max def 2=10660
|mastery bonus atk 2=1098
|mastery bonus def 2=1192
|alignment=Bruiser
|ability=Warhawk
|gender=Male
|usage=Average
|faction=Super Hero
|effect=Significantly harden DEF of your Bruisers.
|centretrait=None

Code I've tried:

if (file_exists('card.xml')) {
    $xml = simplexml_load_file('card.xml');


    $text = $xml->page->revision->text;
    $newtext = explode('|', $text);
    foreach($newtext as $newnewtext) {
        $newtext2 = explode('=', $newnewtext);
        print_r($newtext2);

    }


} else {
    exit('Failed to open card.xml.');
}

Upvotes: 1

Views: 219

Answers (6)

code_monk
code_monk

Reputation: 10130

@Dagon is correct. This is how an implementation might look:

<?php
$keyvalues = array();
$text = file_get_contents('path/to/your/file');
$rows = explode('|',$text);
foereach($rows as $row) {
    if (strpos($row,'=')) {
        $kv = array_map('trim',explode('=',$row));
        $keyvalues[ $kv[0] ] = $kv[1];
    }
}
?>

Upvotes: 0

user557846
user557846

Reputation:

as requested:

<?php
$file="|card name=[Martial] Ares
|character name=Ares
|release_date=May 1 2013
|image 1=MartialAres5.jpg
|rarity 1=Super Special Rare
|pwr req 1=28
|sale price 1=94200
|max card lv 1=60
|max mastery lv 1=40
|quote 1=Ares prefers weapons that were used during the age of Greek myth: sword, axe, and spear.  But he can use any weapon expertly, and turn most ordinary objects into lethal weapons.
|base atk 1=2440
|base def 1=2650
|max atk 1=7015
|max def 1=7613
|mastery bonus atk 1=915
|mastery bonus def 1=993
|image 2=MartialAres6.jpg
|rarity 2=Ultimate Rare
|sale price 2=188400
|max mastery lv 2=200
|quote 2=Next time I see Hercules, We're going to have a steel conversation. It's about time for him to answer for massacring my Stymphalian Birds.
|max atk 2=9822
|max def 2=10660
|mastery bonus atk 2=1098
|mastery bonus def 2=1192
|alignment=Bruiser
|ability=Warhawk
|gender=Male
|usage=Average
|faction=Super Hero
|effect=Significantly harden DEF of your Bruisers.
|centretrait=None";


$x=explode("\n",$file);
$out=array();
foreach($x as $each){
  $xx=explode('=',$each);
 $out[ltrim($xx[0],'|')]=$xx[1]; 
}
echo '<pre>';
print_r($out);

working demo: http://codepad.viper-7.com/3BkXD6

Upvotes: 5

jedrzej.kurylo
jedrzej.kurylo

Reputation: 40909

The simplest and most efficient way to achieve that is using regular expressions. Given that $string holds the data, do the following:

preg_match_all('/^\|(?<key>[^=]+)=(?<value>.*)$/m', $string, $matches);
print_r(array_combine($matches['key'], $matches['value']));

For the data you provided as an example you'll get:

Array
(
  [card name] => [Martial] Ares
  [character name] => Ares
  [release_date] => May 1 2013
  [image 1] => MartialAres5.jpg
  [rarity 1] => Super Special Rare
  [pwr req 1] => 28
  [sale price 1] => 94200
  [max card lv 1] => 60
  [max mastery lv 1] => 40
  ...and so on
)

Upvotes: 1

Maksim Solovjov
Maksim Solovjov

Reputation: 3157

With the minimal error checking:

$text = explode('|', $text);
$result = array();
foreach ($text as $entry) {
    if ($entry) {
        $entry = explode('=', $entry);
        $result[$entry[0]] = $entry[1];
    }
}

Upvotes: 0

dlporter98
dlporter98

Reputation: 1630

First, I would split the string on the '|' charater.

$parts = explode("|", $str);

This will result in an array like the following:

    Array
    (
        [0] => 
        [1] => card name=[Martial] Ares

        [2] => character name=Ares

        [3] => release_date=May 1 2013

        [4] => image 1=MartialAres5.jpg

        [5] => rarity 1=Super Special Rare

        [6] => pwr req 1=28

        [7] => sale price 1=94200

        [8] => max card lv 1=60

        [9] => max mastery lv 1=40

        [10] => quote 1=Ares prefers weapons that were used during the age of Greek myth: sword, axe, and spear.  But he can use any weapon expertly, and turn most ordinary objects into lethal weapons.

        [11] => base atk 1=2440

        [12] => base def 1=2650

        [13] => max atk 1=7015

        [14] => max def 1=7613

        [15] => mastery bonus atk 1=915

        [16] => mastery bonus def 1=993

        [17] => image 2=MartialAres6.jpg

        [18] => rarity 2=Ultimate Rare

        [19] => sale price 2=188400

        [20] => max mastery lv 2=200

        [21] => quote 2=Next time I see Hercules, We're going to have a steel conversation. It's about time for him to answer for massacring my Stymphalian Birds.

        [22] => max atk 2=9822

        [23] => max def 2=10660

        [24] => mastery bonus atk 2=1098

        [25] => mastery bonus def 2=1192

        [26] => alignment=Bruiser

        [27] => ability=Warhawk

        [28] => gender=Male

        [29] => usage=Average

        [30] => faction=Super Hero

        [31] => effect=Significantly harden DEF of your Bruisers.

        [32] => centretrait=None
    )

Next, I would loop over the array and split each string on the "=" character and build an associative array from the pieces.

    //First remove the first empty element from the array.
    array_shift($parts);

    $finalArray = array();
    foreach($parts as $part)
    {
        $b = explode("=", $part);
        $finalArray[$b[0]] = $b[1];
    }

This should result in the structure you are seeking.

Array
(
    [card name] => [Martial] Ares

    [character name] => Ares

    [release_date] => May 1 2013

    [image 1] => MartialAres5.jpg

    [rarity 1] => Super Special Rare

    [pwr req 1] => 28

    [sale price 1] => 94200

    [max card lv 1] => 60

    [max mastery lv 1] => 40

    [quote 1] => Ares prefers weapons that were used during the age of Greek myth: sword, axe, and spear.  But he can use any weapon expertly, and turn most ordinary objects into lethal weapons.

    [base atk 1] => 2440

    [base def 1] => 2650

    [max atk 1] => 7015

    [max def 1] => 7613

    [mastery bonus atk 1] => 915

    [mastery bonus def 1] => 993

    [image 2] => MartialAres6.jpg

    [rarity 2] => Ultimate Rare

    [sale price 2] => 188400

    [max mastery lv 2] => 200

    [quote 2] => Next time I see Hercules, We're going to have a steel conversation. It's about time for him to answer for massacring my Stymphalian Birds.

    [max atk 2] => 9822

    [max def 2] => 10660

    [mastery bonus atk 2] => 1098

    [mastery bonus def 2] => 1192

    [alignment] => Bruiser

    [ability] => Warhawk

    [gender] => Male

    [usage] => Average

    [faction] => Super Hero

    [effect] => Significantly harden DEF of your Bruisers.

    [centretrait] => None
)

Upvotes: 0

Rizier123
Rizier123

Reputation: 59691

This should work for you:

First explode() your string by a new line. Then go through each element with array_map() and explode the substr() with an offset of 1 by an equal sign.

At the end just use array_column() to use the first column as value and the 0 column as key.

$arr = array_column(array_map(function($v){
    return explode("=", substr($v, 1));
}, explode(PHP_EOL, $str)), 1, 0);

print_r($arr);

Upvotes: 0

Related Questions