PHP正则表达式从模式中删除不需要的值

I have a large array of scraped names and prices similar to the following:

Array([0] => apple3 [1] => £0.40 [2] => banana6 [3] => £1.80 [4] => lemon [5] => grape [6] => pear5 [7] => melon4 [8] => £2.32 [9] => kiwi [10] => £0.50)

I would like to remove the fruit names that are not immediately followed by a price. In the above example this would remove: [4] => lemon [5] => grape [6] => pear5 resulting in the following output:

Array([0] => apple3 [1] => £0.40 [2] => banana6 [3] => £1.80 [7] => melon4 [8] => £2.32 [9] => kiwi [10] => £0.50)

If the array needs to be converted to a string in order for me to do this that is not a problem, nor is adding values between the array items in order to aid with regex searches. I have so far been unable to find the correct regular expression to do this using preg_match and preg_replace.

The most important factor is the need to maintain the sequential order of the fruits and prices in order for me at a later stage to convert this into an associative array of fruits and prices.

Thanks in advance.

The following code does both of your tasks at once: getting rid of the fruit without value and turning the result into an associative array of fruits with prices.

$arr = array('apple', '£0.40', 'banana', '£1.80', 'lemon', 'grape', 'pear', 'melon', '£2.32', 'kiwi', '£0.50' );

preg_match_all( '/#?([^£][^#]+)#(£\d+\.\d{2})#?/', implode( '#', $arr ), $pairs );
$final = array_combine( $pairs[1], $pairs[2] );

print_r( $final );

First, the array is converted to a string, separated by '#'. The regex captures all groups of fruits with prices - each stored as a separate subgroup in the result. Combining them into an associative array is a single function call.

Why involve regular expressions? This is doable with a simple foreach loop wherein you iterate over the array and remove names that follow names:

$lastWasPrice = true; // was the last item a price?
foreach ($array as $k => $v) {
    if (ctype_alpha($v)) {
        // it's a name
        if (!$lastWasPrice) {
            unset($array[$k]); // name follows name; remove the second
        }
        $lastWasPrice = false;
    }
    else {
        // it's a price
        $lastWasPrice = true;
    }
}

Simply do this :

  <?php
for($i=0;$i<count($my_array);$i++)
{
if($my_array[$i+1]value=="")
unset($my_array[$i])
}
?>

Something like this might help you

$array = ...;
$index = 0;

while (isset($array[$index + 1])) {
  if (!is_fruit($array[$index + 1])) {
    // Not followed by a fruit, continue to next pair
    $index += 2;
  } else {
    unset($array[$index]);  // Will maintain indices in array
    $index += 1;
  }
}

Not tested though. Also, you need to create the function is_fruit yourself ;)

Without reformatting it, I don't think you can do it with preg_match or preg_replace-- maybe, but nothing is coming to mind.

What is creating that array? If possible, I would alter it to look more like:

Array([apple] => £0.40 [banana] => £1.80 [lemon] => [grape] => '' [pear ] => '' [melon  => £2.32 [kiwi] => £0.50)

Then array_filter($array) is all you'd need to clean it up. If you can't alter the way the original array is created I'd lean towards creating key/value array out of the original.

Try replacing the pattern ** => ([a-zA-Z])** with ** => £0.00 $1**

Basically searching for the context where there is null price and inserting zero pounds.

Hope this helps.

Good luck

assume $a is your array.

function isPrice($str) {
    return (substr($str, 0, 1) == '£');
}
$newA = array();
for($i=0;$i<count($a);$i++) {
    if( isPrice($a[$i]) != isPrice($a[$i+1]) ){
        $newA[] = $a[$i];
    }
}