Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.php > #18865 > unrolled thread

question about preg_replace

Started byalex <1j9448a02@lnx159sneakemail.com.invalid>
First post2022-02-23 15:56 +0100
Last post2022-02-23 21:02 +0000
Articles 11 — 3 participants

Back to article view | Back to comp.lang.php


Contents

  question about preg_replace alex <1j9448a02@lnx159sneakemail.com.invalid> - 2022-02-23 15:56 +0100
    Re: question about preg_replace Mateusz Viste <mateusz@xyz.invalid> - 2022-02-23 16:33 +0100
      Re: question about preg_replace alex <1j9448a02@lnx159sneakemail.com.invalid> - 2022-02-23 16:45 +0100
        Re: question about preg_replace Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2022-02-23 15:49 +0000
          Re: question about preg_replace Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2022-02-23 15:51 +0000
            Re: question about preg_replace alex <1j9448a02@lnx159sneakemail.com.invalid> - 2022-02-23 20:10 +0100
        Re: question about preg_replace Mateusz Viste <mateusz@xyz.invalid> - 2022-02-23 18:06 +0100
          Re: question about preg_replace alex <1j9448a02@lnx159sneakemail.com.invalid> - 2022-02-23 20:14 +0100
    Re: question about preg_replace Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2022-02-23 15:45 +0000
      Re: question about preg_replace alex <1j9448a02@lnx159sneakemail.com.invalid> - 2022-02-23 20:19 +0100
      Re: question about preg_replace Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2022-02-23 21:02 +0000

#18865 — question about preg_replace

Fromalex <1j9448a02@lnx159sneakemail.com.invalid>
Date2022-02-23 15:56 +0100
Subjectquestion about preg_replace
Message-ID<sv5hv3$h8m$2@gioia.aioe.org>
$ echo center | sed -E 's#(.*)#start-\1-end#'
start-center-end

I tried to do the same thing with php, but the result is different

$ php -r "echo preg_replace('#(.*)#', 'start-\0-end', 'center') . PHP_EOL;"
start-center-endstart--end
                 ^^^^^^^^^^

Why?

[toc] | [next] | [standalone]


#18866

FromMateusz Viste <mateusz@xyz.invalid>
Date2022-02-23 16:33 +0100
Message-ID<sv5k3d$1ee0$1@gioia.aioe.org>
In reply to#18865
On 23 Feb 2022 15:56:35 +0100 alex wrote:
> $ echo center | sed -E 's#(.*)#start-\1-end#'
> start-center-end
> 
> I tried to do the same thing with php, but the result is different
> 
> $ php -r "echo preg_replace('#(.*)#', 'start-\0-end', 'center') .
> PHP_EOL;"
> start-center-endstart--end
> 
> Why?

Looks like the preg matches two times: first your 'center' content, and
then what's left (an empty string). I can think of two ways to avoid
that:

Enforce that what's processed has at least one character:

php -r "echo preg_replace('#.(.*)#', 'start-\0-end', 'center') .PHP_EOL;"

Or make sure the preg consumes the entire line:

php -r "echo preg_replace('#^(.*)$#', 'start-\0-end', 'center') .PHP_EOL;"


Mateusz

[toc] | [prev] | [next] | [standalone]


#18868

Fromalex <1j9448a02@lnx159sneakemail.com.invalid>
Date2022-02-23 16:45 +0100
Message-ID<sv5kri$5og$1@gioia.aioe.org>
In reply to#18866
Il 23/02/22 16:33, Mateusz Viste ha scritto:
> php -r "echo preg_replace('#^(.*)$#', 'start-\0-end', 'center') .PHP_EOL;"
> 

Warning: preg_replace(): No ending delimiter '#' found in Command line 
code on line 1

[toc] | [prev] | [next] | [standalone]


#18869

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2022-02-23 15:49 +0000
Message-ID<sv5l2a$k2d$3@dont-email.me>
In reply to#18868
On Wed, 23 Feb 2022 16:45:53 +0100, alex wrote:

> Il 23/02/22 16:33, Mateusz Viste ha scritto:
>> php -r "echo preg_replace('#^(.*)$#', 'start-\0-end', 'center')
>> .PHP_EOL;"
>> 
>> 
> Warning: preg_replace(): No ending delimiter '#' found in Command line
> code on line 1

~ $ php -r "echo preg_replace('#(^.*)#', 'start-\0-end', 'center') . 
PHP_EOL;"
start-center-end
~ $ 




-- 
Lew Pitcher
"In Skills, We Trust"

[toc] | [prev] | [next] | [standalone]


#18870

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2022-02-23 15:51 +0000
Message-ID<sv5l5b$k2d$4@dont-email.me>
In reply to#18869
On Wed, 23 Feb 2022 15:49:31 +0000, Lew Pitcher wrote:

> On Wed, 23 Feb 2022 16:45:53 +0100, alex wrote:
> 
>> Il 23/02/22 16:33, Mateusz Viste ha scritto:
>>> php -r "echo preg_replace('#^(.*)$#', 'start-\0-end', 'center')
>>> .PHP_EOL;"
>>> 
>>> 
>> Warning: preg_replace(): No ending delimiter '#' found in Command line
>> code on line 1
> 
> ~ $ php -r "echo preg_replace('#(^.*)#', 'start-\0-end', 'center') .
> PHP_EOL;"
> start-center-end 

Sorry, wrong example from my testing. How about...

~ $ php -r "echo preg_replace('#^(.*)#', 'start-\0-end', 'center') . 
PHP_EOL;"
start-center-end
~ $ 

It could be that we are running different versions of PHP.
-- 
Lew Pitcher
"In Skills, We Trust"

[toc] | [prev] | [next] | [standalone]


#18872

Fromalex <1j9448a02@lnx159sneakemail.com.invalid>
Date2022-02-23 20:10 +0100
Message-ID<sv60ra$bih$1@gioia.aioe.org>
In reply to#18870
Il 23/02/22 16:51, Lew Pitcher ha scritto:
> On Wed, 23 Feb 2022 15:49:31 +0000, Lew Pitcher wrote:
> 
>> On Wed, 23 Feb 2022 16:45:53 +0100, alex wrote:
>>
>>> Il 23/02/22 16:33, Mateusz Viste ha scritto:
>>>> php -r "echo preg_replace('#^(.*)$#', 'start-\0-end', 'center')
>>>> .PHP_EOL;"
>>>>
>>>>
>>> Warning: preg_replace(): No ending delimiter '#' found in Command line
>>> code on line 1
>>
>> ~ $ php -r "echo preg_replace('#(^.*)#', 'start-\0-end', 'center') .
>> PHP_EOL;"
>> start-center-end
> 
> Sorry, wrong example from my testing. How about...
> 
> ~ $ php -r "echo preg_replace('#^(.*)#', 'start-\0-end', 'center') .
> PHP_EOL;"
> start-center-end
> ~ $
> 
> It could be that we are running different versions of PHP.

thanks

[toc] | [prev] | [next] | [standalone]


#18871

FromMateusz Viste <mateusz@xyz.invalid>
Date2022-02-23 18:06 +0100
Message-ID<sv5pje$keu$1@gioia.aioe.org>
In reply to#18868
On Wed, 23 Feb 2022 16:45:53 +0100
alex <1j9448a02@lnx159sneakemail.com.invalid> wrote:

> Il 23/02/22 16:33, Mateusz Viste ha scritto:
> > php -r "echo preg_replace('#^(.*)$#', 'start-\0-end', 'center')
> > .PHP_EOL;" 
> 
> Warning: preg_replace(): No ending delimiter '#' found in Command
> line code on line 1

That's probably your shell replacing the '$#' pair with nothing.
Escaping the dollar (\$) should help.

Mateusz

[toc] | [prev] | [next] | [standalone]


#18873

Fromalex <1j9448a02@lnx159sneakemail.com.invalid>
Date2022-02-23 20:14 +0100
Message-ID<sv611t$hg5$1@gioia.aioe.org>
In reply to#18871
Il 23/02/22 18:06, Mateusz Viste ha scritto:
> That's probably your shell replacing the '$#' pair with nothing.
> Escaping the dollar (\$) should help.
> 
> Mateusz
> 

exact

[toc] | [prev] | [next] | [standalone]


#18867

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2022-02-23 15:45 +0000
Message-ID<sv5kqr$k2d$1@dont-email.me>
In reply to#18865
On Wed, 23 Feb 2022 15:56:35 +0100, alex wrote:

> $ echo center | sed -E 's#(.*)#start-\1-end#'
> start-center-end
> 
> I tried to do the same thing with php, but the result is different
> 
> $ php -r "echo preg_replace('#(.*)#', 'start-\0-end', 'center') .
> PHP_EOL;"
> start-center-endstart--end
>                  ^^^^^^^^^^
> 
> Why?

First off, it is necessary to recognize that sed(1) uses, depending on 
the options given, either POSIX basic regular expressions (BREs) or
POSIX extended regular expressions (EREs), while PHP's preg_* functions
use Perl-compatable regular expressions (PCREs). These two types of
RE (POSIX and PCRE) have differences in how they match REs, which
would explain why you get different results from sed(1) and php 
preg_replace()


As for PHP preg_replace(), the function will /repeat/ the substitution
as often as possible, if you do not specify a limit. What
 preg_replace('#(.*)#', 'start-\0-end', 'center')
does is
 - match .* to the entire string 'center',
 - because of the grouping brackets in the RE, and the reference in
   the replacement string, it now replaces 'center' with
   'start-center-end', and continues onward in the string. It now
 - matches .* to the empty string at the end of 'center' (remember,
   .* will match ZERO or more occurrences of ANY character), and
 - replaces that empty string with the replacement string. It then
 - runs out of string, and terminates.

You have a couple of possible changes that you can apply to
bring your PHP closer to sed(1):
1) you can limit your RE to one occurrence:
   preg_replace('#(.*)#', 'start-\0-end', 'center',1)

or

2) you can anchor your RE to the start of the string:
   preg_replace('#^(.*)#', 'start-\0-end', 'center')
   preg_replace('#(^.*)#', 'start-\0-end', 'center')


HTH
-- 
Lew Pitcher
"In Skills, We Trust"

[toc] | [prev] | [next] | [standalone]


#18874

Fromalex <1j9448a02@lnx159sneakemail.com.invalid>
Date2022-02-23 20:19 +0100
Message-ID<sv61bc$lqm$1@gioia.aioe.org>
In reply to#18867
Il 23/02/22 16:45, Lew Pitcher ha scritto:
> On Wed, 23 Feb 2022 15:56:35 +0100, alex wrote:
> 
>> $ echo center | sed -E 's#(.*)#start-\1-end#'
>> start-center-end
>>
>> I tried to do the same thing with php, but the result is different
>>
>> $ php -r "echo preg_replace('#(.*)#', 'start-\0-end', 'center') .
>> PHP_EOL;"
>> start-center-endstart--end
>>                   ^^^^^^^^^^
>>
>> Why?
> 
> First off, it is necessary to recognize that sed(1) uses, depending on
> the options given, either POSIX basic regular expressions (BREs) or
> POSIX extended regular expressions (EREs), while PHP's preg_* functions
> use Perl-compatable regular expressions (PCREs). These two types of
> RE (POSIX and PCRE) have differences in how they match REs, which
> would explain why you get different results from sed(1) and php
> preg_replace()
> 
> 
> As for PHP preg_replace(), the function will /repeat/ the substitution
> as often as possible, if you do not specify a limit. What
>   preg_replace('#(.*)#', 'start-\0-end', 'center')
> does is
>   - match .* to the entire string 'center',
>   - because of the grouping brackets in the RE, and the reference in
>     the replacement string, it now replaces 'center' with
>     'start-center-end', and continues onward in the string. It now
>   - matches .* to the empty string at the end of 'center' (remember,
>     .* will match ZERO or more occurrences of ANY character), and
>   - replaces that empty string with the replacement string. It then
>   - runs out of string, and terminates.
> 
> You have a couple of possible changes that you can apply to
> bring your PHP closer to sed(1):
> 1) you can limit your RE to one occurrence:
>     preg_replace('#(.*)#', 'start-\0-end', 'center',1)
> 
> or
> 
> 2) you can anchor your RE to the start of the string:
>     preg_replace('#^(.*)#', 'start-\0-end', 'center')
>     preg_replace('#(^.*)#', 'start-\0-end', 'center')
> 
> 
> HTH

thanks

[toc] | [prev] | [next] | [standalone]


#18875

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2022-02-23 21:02 +0000
Message-ID<sv67d0$k2d$5@dont-email.me>
In reply to#18867
On Wed, 23 Feb 2022 15:45:31 +0000, Lew Pitcher wrote:

> On Wed, 23 Feb 2022 15:56:35 +0100, alex wrote:
> 
>> $ echo center | sed -E 's#(.*)#start-\1-end#'
>> start-center-end
>> 
>> I tried to do the same thing with php, but the result is different
>> 
>> $ php -r "echo preg_replace('#(.*)#', 'start-\0-end', 'center') .
>> PHP_EOL;"
>> start-center-endstart--end
>>                  ^^^^^^^^^^
>> 
>> Why?

[snip]

> You have a couple of possible changes that you can apply to bring your
> PHP closer to sed(1):
> 1) you can limit your RE to one occurrence:
>    preg_replace('#(.*)#', 'start-\0-end', 'center',1)
> 
> or
> 
> 2) you can anchor your RE to the start of the string:
>    preg_replace('#^(.*)#', 'start-\0-end', 'center')
>    preg_replace('#(^.*)#', 'start-\0-end', 'center')

You could also change the RE so that it matches ONE OR MORE characters,
preventing it from matching the empty string at the end of the data.
    preg_replace('#(.+)#', 'start-\0-end', 'center')



-- 
Lew Pitcher
"In Skills, We Trust"

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.php


csiph-web