[Webinar] Learn how to a build a cloud-first strategyRegister Now


replace a string unless encapsulated

Posted on 2011-05-08
Medium Priority
Last Modified: 2012-05-11
If I have a string like this
$string = "{fantastic|great|brilliant}! This is great";
If I would like to replace the bolded great only in this, and not anything that occurs between the { and } characters.
how would I go about that?

Question by:paulp75
LVL 19

Expert Comment

by:Greg Alexander
ID: 35717240
Like this:

$string = "{fantastic|great|brilliant}! This is great";
$new_string = explode(" ",$string);
$new_string = implode(" ",$new_string);
echo $new_string;

Open in new window

LVL 75

Expert Comment

by:käµfm³d 👽
ID: 35717266
If you can safely assume that the words adjoining "great" inside the braces will be there, and be in that order, then you can do something like the following. If you instead will not know the words inside the braces, then it might be a bit more difficult and you might have to look into something like explode().
$string = "{fantastic|great|brilliant}! This is great";

$result = preg_replace('/(?<!{fantastic\\|)great(?!\\|brilliant})/', "replacement", $string);

echo $result;

Open in new window


Author Comment

ID: 35717380
Thanks for the replies, but none will get the result that I require.
what actually happens is it runs through a loop of cases. I can't assume where the words will be etc. They might have white space or might not (it comes from another variable)

so this might actually be a article that is 500 words or so.

but it will need to find cases of each one, and replace it.
so the words would vary each time.

In the example, the word great would likely be getting replaced by a line of text in a text file.

$newtext = str_replace($phrase, "{" . $line . "}", $newtext);

but how would I replace only the ones not inside the {}'s
this {is not|will not|should not} to be replaced, however this should not be missed
In the above example, on the instance that is not inside the { and } should be replaced.
This will be replaced by a similar text with { and } afterward and multiple terms.
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

LVL 75

Expert Comment

by:käµfm³d 👽
ID: 35719623
How about this? You can change the "temp" replacement (##########) to whatever you like; just make sure it's not a string that already exists in your source string.
$string = "{fantastic|great|brilliant}! This is great{fantastic|great|brilliant}";

preg_match_all('/{[^}]*}/', $string, $matches);

$result = preg_replace('/{[^}]*}/', '##########', $string);

$result = str_replace('great', 'replacement', $result);

for ($i = 0; $i < count($matches); $i++)
    $count = 1;

    $result = str_replace('##########', $matches[$i][0], $result, $count);

echo $result;

Open in new window

LVL 111

Expert Comment

by:Ray Paseur
ID: 35720185
Thanks for the replies, but none will get the result that I require.

That's because the problem definition in the original question is not semantically clear.  Here is what might get you a better answer...

Create a small set of test cases that demonstrate the variations on the theme.  For each test case, manually create the exact result output you would expect to get after processing.  Post those test and results sets here and let the question be, "What is a generalized, best-practices, method of handling this?"  This is one of the steps in test-driven design, and it makes for very easy and accurate program development.
LVL 13

Accepted Solution

Carl Bohman earned 2000 total points
ID: 35720990
String: great{fantastic|great|brilliant}! This is great{fantastic|great|brilliant}greatgreatgre atgreat
Regex: /(?:^|\G)([^{]*?(?:\{[^}]*\}[^{]*?)*?)(great)/
Replacement: \1FOO

I ran my regex through an online regex tester (http://www.myregextester.com/index.php) and it seemed to work as described.  Here's some (untested) source code that should do what you are looking for:

$sourcestring="great{fantastic|great|brilliant}! This is great{fantastic|great|brilliant}greatgreatgre atgreat";
echo preg_replace('/(?:^|\G)([^{]*?(?:\{[^}]*\}[^{]*?)*?)(' . $searchstring . ')/', '\1' . $replacestring, $sourcestring);

Open in new window

LVL 75

Expert Comment

by:käµfm³d 👽
ID: 35721059

Nice  : )

Author Closing Comment

ID: 35743682
Fantastic solution. thank you very much.

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
This article discusses how to create an extensible mechanism for linked drop downs.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to count occurrences of each item in an array.
Suggested Courses
Course of the Month20 days, 10 hours left to enroll

868 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question