Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Shaun E on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Masking parts of a string (hopefully with preg_replace) 1

Status
Not open for further replies.

karnaf

Programmer
Nov 16, 2002
41
IL
I've been trying to solve this one using regular expressions (preg_replace) but can't find the solution. Thought I'd ask for the good people's advice. B-)

I have a string which has a few [tags] in it. I want to replace everything between the start [tag] and the end [/tag] with some character (same one), but it's important I maintain the number of characters in between the tags.

Example:

[tt]this is [tag]a sample[/tag] of text for [tag]masking[/tag] just parts [tag]of it[/tag], see?[/tt]

will be changed into:

[tt]this is [tag]########[/tag] of text for [tag]#######[/tag] just parts [tag]#####[/tag], see?[/tt]

The string may have no tags at all, in which case nothing should change.
For matters of simplicity, there is only one type of tag (e.g. [tag]text[/tag]). In the real case there are 4-5, but all known in advance (constants).
The same tag may appear more than once in the string.

I was thinking of something like
[tt]$str = preg_replace("/\[tag\]?[\w|\s]*\[\/tag\]?/i",
"[tag]#[/tag]",
$str);[/tt]
But it doesn't "count" the number of character, meaning it gives me the following result:

[tt]this is [tag]#[/tag] of text for [tag]#[/tag] just parts [tag]#[/tag], see?[/tt]

Help me. Plllllllllease [hourglass]

Thanks!!! [peace]

Karnaf
 

Oh. Forgot to say that I'm looking for a regular expression solution. I can do normal string manipulations easily, just interested in a more elegant solution (and a chance to learn a little more about reg exps.)

Again, thanks.

Karnaf
[bigears]
 
Gee, I feel like I'm talking to myself here :-D

Here's that string manipulation option...

[tt]
$start_pos= -1 ;
$tags = array("tag", "none", "thistag");

for ($i=0; $i<count($tags); $i++)
{
$tag_length = strlen($tags[$i])+2;
while ($start_pos = strpos($str, "[$tags[$i]]", $start_pos+1))
{
if ($end_pos = strpos($str, "[/$tags[$i]]", $start_pos))
{
$str = substr($str, 0, $start_pos+$tag_length) .
str_repeat("#", ($end_pos-$start_pos)-$tag_length) .
substr($str, $end_pos);
}
}
}
[/tt]

But I still hope to get a one line solution....


karnaf.
 
Has anyone ever told you that you have the patience of a cat? Tip: You're going to get answers here on other peoples' timetables, not yours.

I don't think you're going to find a single preg_replace() invocation that will do it all. It might be possible in perl, but PHP only implements parts of perl's regular expression system.

I'd use preg_split() to split the string into an array at the open tags, edit those elements of the resultant array where the close tags appear, then recombine the array into a string.

Want the best answers? Ask the best questions!

TANSTAAFL!!
 

LOL

No, no one has ever told me I have the patience of a cat. I didn't even know that proverb existed until now. sorry if I seemed impatient, far from it, it is just that there is no option to edit existing posts. everytime I recalled something I wanted to say and forgot to say it the first time, I added it as a new post ::)

An answer that my problem can't be solved with reg exps will be acceptable too B-)

Anyway, if anyone does have the time and the knowledge, that'd be cool. Do it on your own timetable... [2thumbsup]

And BTW, there's a bug in my string manipulation solution - the [tt]$start_pos= -1;[/tt] should be inside the for loop...

That's all folks

karnaf
[bigears]
 
Karnaf,
We've let you wait long enough. Here's a suggestion that uses PCRE:
Code:
$str = preg_replace("/(\[tag\])(.*)(\[\/tag\])/e","'\\1'.str_repeat('#',strlen('\\2')).'\\3'",$str);

This regex captures the subpatterns and uses the /e modifier to execute the second argument in preg_replace as PHP code. There is a similar thing in PERL. It will give you in one line exactly what you want. This will work fine, some more tuning would be needed if there were nested tags.
Hope your waiting paid off.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top