2

I would like to replace : with \xEF\xBC\x9A however, I do not want to do this for : that follows http, https, and string with the format of @[{numbers}:{numbers}:{some text}]. What I have doesn't really work as (?<!@\[\d) does not check what's after it. My current implementation only work for something like @[1:2:text].

$string = preg_replace(
    '#(?<!https)(?<!http)(?<!@\[\d)(?<!@\[\d:\d):#',
    "\xEF\xBC\x9A",
    $string
);

3 Answers 3

1

Try this:

preg_replace('/(@\[\d+:\d+:[^]]*]|https?:)|:/e', '"$1"?"$1":"\xEF\xBC\x9A"', $string);
Sign up to request clarification or add additional context in comments.

6 Comments

Umm I am getting Unknown modifier 'g': [/(@[\d+:\d+:[^]]*]|https?:)|:/ge]
This appears to select instances of 'http:', 'https:', and '@[/d:/d:/t*]', which is opposing the point made in the question itself, I suggest rewording the question if this is the correct answer.
@Qtax, is there a way I can do this without /e?
@Dessix: The idea is to capture the "ineligible" colon along with the text preceding it, and plug it back in. That "gets it out of the way", so when the other alternative matches a colon, you know it's one of the ones you want to replace.
@hao: You can do this without /e, but I don't recommend it: demo.
|
0

Try this regex:

(?<!@\[(?::?[\d]{0,5}){1,2})(?<!https?):

It should match the first and second instances of ':' here.

: test: http: @[1:2:text]

Usage Sample:

$string = preg_replace('/(?<!@\[(?::?[\d]{0,5}){1,2})(?<!https?):/', '\xEF\xBC\x9A', $string);

1 Comment

A lookbehind has to match a fixed number of characters (in PHP, at least). That's why the OP used (?<!https)(?<!http) instead of (?<!https?). But it's impossible to "fake" the whole problem that way, as the OP has discovered.
0

Match the expressions that should not be mutated then disqualify them with (*SKIP)(*FAIL) -- this is far simpler than trying to avoid matching them. Then match any non-disqualified colon and replace it with the desired string.

Code: (Demo)

$string = <<<TEXT
foo : test: http: @[1:2:text] http://example.com 3:4
TEXT;

echo preg_replace(
    '/(?:https?:|@\[\d+:\d+:[^\]]+)(*SKIP)(*FAIL)|:/',
    '\xEF\xBC\x9A',
    $string
);

Output:

foo \xEF\xBC\x9A test\xEF\xBC\x9A http: @[1:2:text] http://example.com 3\xEF\xBC\x9A4

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.