开发者

Problem with regex and preg_match_all

开发者 https://www.devze.com 2023-02-18 00:14 出处:网络
I have a very long string similar too : $text = \"[23,64.2],[25.2,59.8],[25.6,60],[24,51.2],[24,65.2],[3.4,63.4]\";

I have a very long string similar too :

$text = "[23,64.2],[25.2,59.8],[25.6,60],[24,51.2],[24,65.2],[3.4,63.4]";

They are coordinates. I'd like to extract every x,y from the []s I really hate regex, i still have problems to write it correctly

I tried

开发者_Python百科$pattern = "#\[(.*)\]#";
preg_match_all($pattern, $text, $matches);

But it didn't work. Any one could help me please ?


You need to make the asterisk "lazy":

$pattern = "#\[(.*?)\]#";

But how about this?

$pattern = "#\[(\d+(\.\d+)?),(\d+(\.\d+)?)\]#";

On your code, this would produce

Array
(
    [0] => Array
        // ...

    [1] => Array
        (
            [0] => 23
            [1] => 25.2
            [2] => 25.6
            [3] => 24
            [4] => 24
            [5] => 3.4
        )

    [2] => Array
        //...

    [3] => Array
        (
            [0] => 64.2
            [1] => 59.8
            [2] => 60
            [3] => 51.2
            [4] => 65.2
            [5] => 63.4
        )

    [4] => Array
        //...
)


You should use .*? to make it less greedy. Otherwise it is likely to match too long substrings. It's also sometimes helpful to use a negated character class, ([^[\]]*) in your case.

But it's always best to be extra specific about what you want:

preg_match_all("#\[([\d,.]+)]#", $text, $matches);

This way it will only match \decimals and commas and dots. Oops, and the opening [ needs to be escaped.

preg_match_all("#\[([\d.]+),([\d.]+)]#", $text, $matches, PREG_SET_ORDER);

Would already give you the X and Y coordinates separated. Try also PREG_SET_ORDER as fourth parameter, which will give you:

Array
(
    [0] => Array
        (
            [0] => [23,64.2]
            [1] => 23
            [2] => 64.2
        )

    [1] => Array
        (
            [0] => [25.2,59.8]
            [1] => 25.2
            [2] => 59.8
        )

    [2] => Array
        (
            [0] => [25.6,60]
            [1] => 25.6
            [2] => 60
        )


This should do it:

$string = '[23,64.2],[25.2,59.8],[25.6,60],[24,51.2],[24,65.2],[3.4,63.4]';
if (preg_match_all('/,?\[([^\]]+)\]/', $string, $matches)) {
  print_r($matches[1]);
}

It prints:

[0] => string(7) "23,64.2"
[1] => string(9) "25.2,59.8"
[2] => string(7) "25.6,60"
[3] => string(7) "24,51.2"
[4] => string(7) "24,65.2"
[5] => string(8) "3.4,63.4"

A breakdown of the regexp:

,?        // zero or one comma
\[        // opening bracket
([^\]]+)  // capture one or more chars until closing bracket
\]        // closing bracket

To get the x, y coordinates, you could then:

$coords = array();
foreach ($matches[1] as $match) {
  list($x, y) = explode(',', $match);
  $coords[] = array(
     'x' => (float)$x,
     'y' => (float)$y
  );
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号