0

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?

2
  • hmm, is it ok that ther no comma between bool dxDrawImage and float posX in input string? Commented Jul 21, 2012 at 13:05
  • Oh, of course. I forgot that there is separator between other parts of string... Thank you! Commented Jul 21, 2012 at 13:10

4 Answers 4

1
preg_match_all("/(\b(?:bool|float|int|element)\s+.*?)(?=\b(?:bool|float|int|element|[,;\n\r]|$))/", $txt, $ar); 
print_r($ar[1]);
Sign up to request clarification or add additional context in comments.

Comments

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);

2 Comments

But, this float rotationCenterOffsetX = 0 wouldn't be captured.
Although I can replace this by making, for example, float rotationCenterOffsetX=0, but I need spaces between equals sign.
0

Maybe you can use the ungreedy flag.

preg_match_all("/(bool|float|int)[a-zA-Z0-9\s=]+/U", $txt, $ar);

2 Comments

AFAIK, It will match only bool, float or int
Warning: preg_match_all() expects parameter 4 to be long, string given
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.