preg_match_all ? quantifier problem

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Han

    preg_match_all ? quantifier problem

    The following pattern (which is one subpattern in a string of several) looks
    for the following

    $xxx,xxx.xx (with the dollar sign)

    or

    xxx,xxx.xx (space in replace of missing dollar sign)

    It works great WITHOUT a ? quantifier

    ((?:\\$|\s*)(?: \d{1,3}\,)?\d{1 ,3}\.\d{2}(?:</b>))

    but fails WITH a ? quantifier

    ((?:\\$|\s*)(?: \d{1,3}\,)?\d{1 ,3}\.\d{2}(?:</b>))?

    I need the rest of the pattern results, not matter if this subpattern exists
    or not. If it doesn't exist, I need the respective array value to be empty.

    What's wrong with my syntax?

    Thanks.


  • Thomas Mlynarczyk

    #2
    Re: preg_match_all ? quantifier problem

    Also sprach Han:
    [color=blue]
    > The following pattern (which is one subpattern in a string of
    > several) looks for the following
    >
    > $xxx,xxx.xx (with the dollar sign)
    >
    > or
    >
    > xxx,xxx.xx (space in replace of missing dollar sign)
    >
    > It works great WITHOUT a ? quantifier
    >
    > ((?:\\$|\s*)(?: \d{1,3}\,)?\d{1 ,3}\.\d{2}(?:</b>))
    >
    > but fails WITH a ? quantifier
    >
    > ((?:\\$|\s*)(?: \d{1,3}\,)?\d{1 ,3}\.\d{2}(?:</b>))?[/color]

    It does not fail, but it gives unexpected results. This regex translates
    into "match the above pattern OR match an empty string".
    [color=blue]
    > I need the rest of the pattern results, not matter if this subpattern
    > exists or not.[/color]

    preg_match_all will give you all the matches it finds. Just have a look at
    the array of found matches (print_r()).
    [color=blue]
    > If it doesn't exist, I need the respective array value
    > to be empty.[/color]

    $test = '$123,123.12</b> $1,1.1</b> $23,23.23</b>';
    $pattern = '/(?:\\$|\s*)(?:\ d{1,3}\,)?\d{1, 3}\.\d{2}(?:</b>)/';
    preg_match_all( $pattern, $test, $result);
    echo '<pre>'; print_r($result ); echo '</pre>';

    Note that I stripped the additional parentheses around the whole regex.
    Now, $result should be:

    $result[0] = '$123,123.12</b>'
    $result[1] = '$23,23.23</b>'
    (as '$1,1.1</b>' does not match)

    Do I understand you right, that, in the above case, you would like $result
    to be

    $result[0] = '$123,123.12</b>'
    $result[1] = ''
    $result[2] = '$23,23.23</b>'

    Well, that would be a bit more difficult (Remember, that anything could be
    there instead of the "almost correct" $1,1.1</b>). You'd have to extend your
    regex to something like "Match the valid pattern as before and capture them
    with parentheses nr. 1 (that's your original regex) OR match any invalid
    pattern, but don't capture them." Then use preg_match_all with the flag
    PREG_SET_ORDER and in the result array, check for every index if
    second-level index 1 exists. If so, it should contain your valid subpattern,
    if not, then you have an invalid pattern at second-level index 0.

    Greetings, Thomas


    Comment

    • Han

      #3
      Re: preg_match_all ? quantifier problem

      Thom,

      Thanks for your reply.

      It seems like trying to include this and other conditional requirements in
      one pass might be asking for too much. It will ultimately be much easier to
      simply capture larger blocks of markup and parse them accordingly upon
      outputting to the page.

      Your explanation was very instructive though and I sincerely appreciate your
      time.

      "Thomas Mlynarczyk" <blue_elephant5 5@hotmail.com> wrote in message
      news:bm0qd3$rs6 $05$1@news.t-online.com...[color=blue]
      > Also sprach Han:
      >[color=green]
      > > The following pattern (which is one subpattern in a string of
      > > several) looks for the following
      > >
      > > $xxx,xxx.xx (with the dollar sign)
      > >
      > > or
      > >
      > > xxx,xxx.xx (space in replace of missing dollar sign)
      > >
      > > It works great WITHOUT a ? quantifier
      > >
      > > ((?:\\$|\s*)(?: \d{1,3}\,)?\d{1 ,3}\.\d{2}(?:</b>))
      > >
      > > but fails WITH a ? quantifier
      > >
      > > ((?:\\$|\s*)(?: \d{1,3}\,)?\d{1 ,3}\.\d{2}(?:</b>))?[/color]
      >
      > It does not fail, but it gives unexpected results. This regex translates
      > into "match the above pattern OR match an empty string".
      >[color=green]
      > > I need the rest of the pattern results, not matter if this subpattern
      > > exists or not.[/color]
      >
      > preg_match_all will give you all the matches it finds. Just have a look at
      > the array of found matches (print_r()).
      >[color=green]
      > > If it doesn't exist, I need the respective array value
      > > to be empty.[/color]
      >
      > $test = '$123,123.12</b> $1,1.1</b> $23,23.23</b>';
      > $pattern = '/(?:\\$|\s*)(?:\ d{1,3}\,)?\d{1, 3}\.\d{2}(?:</b>)/';
      > preg_match_all( $pattern, $test, $result);
      > echo '<pre>'; print_r($result ); echo '</pre>';
      >
      > Note that I stripped the additional parentheses around the whole regex.
      > Now, $result should be:
      >
      > $result[0] = '$123,123.12</b>'
      > $result[1] = '$23,23.23</b>'
      > (as '$1,1.1</b>' does not match)
      >
      > Do I understand you right, that, in the above case, you would like $result
      > to be
      >
      > $result[0] = '$123,123.12</b>'
      > $result[1] = ''
      > $result[2] = '$23,23.23</b>'
      >
      > Well, that would be a bit more difficult (Remember, that anything could be
      > there instead of the "almost correct" $1,1.1</b>). You'd have to extend[/color]
      your[color=blue]
      > regex to something like "Match the valid pattern as before and capture[/color]
      them[color=blue]
      > with parentheses nr. 1 (that's your original regex) OR match any invalid
      > pattern, but don't capture them." Then use preg_match_all with the flag
      > PREG_SET_ORDER and in the result array, check for every index if
      > second-level index 1 exists. If so, it should contain your valid[/color]
      subpattern,[color=blue]
      > if not, then you have an invalid pattern at second-level index 0.
      >
      > Greetings, Thomas
      >
      >[/color]


      Comment

      Working...