0

I am trying to replace every match of the following string with '' but leave the curly brackets and the text inside. There is also text surrounding the span elements, and there are multiple tags with tag_item varying and Tag title varying.

Example string:

Text text text text 
<span contenteditable="false" data-tag="{{tag_item}}">Tag Title</span>
Text text text text 
<span contenteditable="false" data-tag="{{tag_item2}}">Tag Title2</span>
Text text text text 

And I would like it to become:

Text text text text 
{{tag_item}}
Text text text text 
{{tag_item2}}
Text text text text 

Here is what I have so far, and it is not working:

$message = preg_replace('/" contenteditable="false">(.*)<\/span>/i', '', $message);

$message = str_replace('<span data-tag="', '', $message);

Thanks in advance.

4
  • Is that example string the only content? Mention a bit more context / use case. Wouldn't just searching for {{tags}} and throwing everything else away be simpler? Commented Nov 22, 2013 at 4:02
  • @mario, see updated question. There will be text surrounding the spans and there will be multiple spans. Commented Nov 22, 2013 at 4:07
  • Are there other tags besides <span .. ? Commented Nov 22, 2013 at 4:19
  • Yes there can be p tags, font tags, etc. It's being used inside ckeditor if that helps for the types of available tags that are in use. Commented Nov 22, 2013 at 4:20

5 Answers 5

3

You can do this:

$m = preg_replace ('/<span contenteditable="false" data-tag=\"/i','',$message);
$answer = preg_replace ('/\">.*?<\/span>/i', '' ,$m);
Sign up to request clarification or add additional context in comments.

Comments

0

Is this what you're looking for?

$message = preg_replace('/.data-tag="(.)".*/', '$1', $message);

Comments

0

Well, then do it in one regex:

= preg_replace("#
    <(\w+) [^>]* (\{\{\w+\}\}) [^>]*>
    (.*?)
    </\1>
#smix", "$2 $3", $src)

This just looks for your {{tag}} and everything whatever just with it $2 and the text $3 between angle brackets.

Comments

0

Don't use Regex to parse HTML, use the DOM.

$html = <<<'HTML'
Text text text text 
<span contenteditable="false" data-tag="{{tag_item}}">Tag Title</span>
Text text text text 
<span contenteditable="false" data-tag="{{tag_item2}}">Tag Title2</span>
Text text text text 
HTML;

$dom = new DOMDocument();
$dom->loadHtml($html);
$xpath = new DOMXpath($dom);

$expression = '//text()[not(parent::*[@data-tag])]|//*[@data-tag]/@data-tag';

foreach ($xpath->evaluate($expression) as $node) {
  switch ($node->nodeType) {
  case XML_TEXT_NODE :
    echo $node->nodeValue;
    break;
  case XML_ATTRIBUTE_NODE :
    echo $node->value;
    break;
  }
}

The Expression

The Xpath expression matches all text nodes, if the parent is not an element with a data-tag attribute and all data-tag attributes.

Match all text nodes at any position in the DOM:

//text()

Limit that to the nodes where the parent has no "data-tag" attribute

[not(parent::*[@data-tag])]

Or

|

Select all data-tag attributes

@data-tag

Comments

0

If I understand correctly your question, maybe this can be your solution

$message = preg_replace('/<\w+\s+contenteditable="false"\s+data-tag="({{.*}})">.*<\/\w+>/imsU', '$1', $message);

The option "U" is for Ungreedy and try to find the shortest occurence instead of the longest for all countable elements (I mean elements which are followed by "?", "+" or "*").

You can have more options on this page: http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

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.