I have strings, for example:
bool dxDrawImage float posX, float posY, float width, float height, mixed image , float rotation = 0, float rotationCenterOffsetX = 0, float rotationCenterOffsetY = 0, int color = white, bool postGUI = false
bool dxUpdateScreenSource element screenSource, bool resampleNow =false
I need get parts from it, for example:
bool dxDrawImage
float posX
float posY
...
I wrote:
preg_match_all("/(bool|float|int)[a-zA-Z0-9\s=]+/", $txt, $ar);
print_r($ar):
Array ( [0] => Array ( [0] => bool dxDrawImage float posX [1] => float posY [2] => float width [3] => float height [4] => float rotation = 0 [5] => float rotationCenterOffsetX = 0 [6] => float rotationCenterOffsetY = 0 [7] => int color = white [8] => bool postGUI = false ) [1] => Array ( [0] => bool [1] => float [2] => float [3] => float [4] => float [5] => float [6] => float [7] => int [8] => bool ) )
Why this regexp capture bool dxDrawImage float posX
instead
bool dxDrawImage
float posX
How to fix this?
preg_match_all("/(\b(?:bool|float|int|element)\s+.*?)(?=\b(?:bool|float|int|element|[,;
]|$))/", $txt, $ar);
print_r($ar[1]);
You may disallow whitespaces in variable name:
preg_match_all("/(bool|float|int)\s+[a-zA-Z0-9=]+/", $txt, $ar);
What if you will use:
preg_match_all("/(bool|float|int)\s+[a-zA-Z0-9]+(\s+=\s+[chars,possible for value]+)?/", $txt, $ar);
Maybe you can use the ungreedy flag.
preg_match_all("/(bool|float|int)[a-zA-Z0-9\s=]+/U", $txt, $ar);
The part that delimits one variable from the other is a bit unclear in your string. That makes it a bit hard to separate each from another. However, you can relatively simple still write the pattern as it occurs:
((?:bool|float|mixed|int|element) [a-zA-Z]+(?: = ?[a-z0-9]+)?)(?:\s?,\s?|\s|$)
|^-------- variable type -------^ | ^--- optional ---^|^-- delimiter -^
| name |
| |
`------------------ the interesting part --------------------´
Such a pattern works with preg_match_all
:
$pattern = '(((?:bool|float|mixed|int|element) [a-zA-Z]+(?: = ?[a-z0-9]+)?)(?:\s?,\s?|\s|$))';
$variables = array();
if ($r = preg_match_all($pattern, $subject, $matches)) {
$variables = $matches[1];
}
print_r($variables);
Output:
Array
(
[0] => bool dxDrawImage
[1] => float posX
[2] => float posY
[3] => float width
[4] => float height
[5] => mixed image
[6] => float rotation = 0
[7] => float rotationCenterOffsetX = 0
[8] => float rotationCenterOffsetY = 0
[9] => int color = white
[10] => bool postGUI = false
[11] => bool dxUpdateScreenSource
[12] => element screenSource
[13] => bool resampleNow =false
)
The other alternative is to only use the delimiter and split the string. However after the delimiter a variable type plus space follows (look-ahead):
$pattern = '((?:\s?,\s?|\s)(?=(?:bool|float|mixed|int|element)))';
$variables = preg_split($pattern, $subject);
print_r($variables);
It gives you the same result as above.