1

I have seen this question which relevant for me, but I have one additional condition to add and I don't know how to approach that.

\[(.*?)\]

Right now this code will extract everything inside the square brackets, but I wish to extract only numbers.

Assuming I have the following expression [+₪7.00], I wish to extract only 7.00 or 7.

How can I extract only number from square brackets using regular expression?

Edit:

This is what I tried so far:

\[([^\d])\]

[^\d] suppose to extract only numbers from string, but that doesn't work here.

Also it will give me 700 instead of 7 because of the dot in 7.00

EDIT:

//Add Addons & Prices
if($slug == "addon"){
    $temp = explode(',', $value);
    $group = [];
    foreach($temp as $t){
        echo $t;
        $regex = "/\[[^][\d]*\K\d+(?:\.\d+)?(?=[^][]*])/";
        $price = 0;
        $str = $t;
        if (preg_match_all($regex, $str, $matches)) {
            foreach ($matches[0] as $match => $m) {
                $price = $m;
             }
        }
        echo $price;
        echo '<br/>';
        $g = [
            'name' => $t,
            'values' => [
                [
                    'id' => 0,
                    'name' => $t,
                    'price' => $price
                ]
            ]
        ];
        array_push($group, $g);
    }
}
ExCluSiv3
  • 184
  • 2
  • 20

1 Answers1

1

To extracrt a single number from in between square brackets, you can use

\[[^][\d]*\K\d+(?:\.\d+)?(?=[^][]*])

See the regex demo. Details:

  • \[ - a [ char
  • [^][\d]* - zero or more chars other than [, ] and digits
  • \K - match reset operator that discards all text matched so far from the current overall match memory buffer
  • \d+(?:\.\d+)? - one or more digits followed with an optional sequence of a . and one or more digits
  • (?=[^][]*]) - a positive lookahead that requires zero or more chars other than [ and ] and then a ] char immediately to the right of the current location.

See a PHP demo:

$re = '/\[[^][\d]*\K\d+(?:\.\d+)?(?=[^][]*])/';
$str = 'I have the following expression [+₪7.00], I wish to extract only 7.00 or 7.';
if (preg_match_all($re, $str, $matches)) {
   print_r($matches[0]);
}
// => Array( [0] => 7.00 )

Just in case you have multiple numbers to extract...

Then, you can use

(?:\G(?!\A)|\[)[^][\d]*\K\d+(?:\.\d+)?(?=[^][]*])

See this regex demo. (?:\G(?!\A)|\[) matches the end of the previous successful match or a [ char.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • I have another issue with that, I have Hebrew in my string, and the regex doesn't work with Hebrew, what could cause that? This is my string: `בולגרית [+₪7.00]` - Debug result: `8362` instead of `7.00` – ExCluSiv3 Feb 06 '21 at 15:09
  • @ExCluSiv3 Could you please check [this demo](https://3v4l.org/AWhq7)? I do not see any issue. – Wiktor Stribiżew Feb 06 '21 at 15:18
  • That's weird, when I extract value from an array using foreach loop (`בולגרית [+₪7.00]`) I get `8362`, but when using the same string (instead of getting it out of the array) I get the correct value (`7.00`). I can't understand why is this happening, got any idea? – ExCluSiv3 Feb 06 '21 at 15:27
  • @ExCluSiv3 `$re = '/\[[^][\d]*\K\d+(?:\.\d+)?(?=[^][]*])/u';` – Wiktor Stribiżew Feb 06 '21 at 15:30
  • I understand why this happens, the currency symbol `₪` equals to `8362` hex code, how can I filter him? – ExCluSiv3 Feb 06 '21 at 15:36
  • 1
    @ExCluSiv3 You probably need to use `html_entity_decode($str)` instead, to convert entities to literal characters. – Wiktor Stribiżew Feb 06 '21 at 16:51