简体   繁体   中英

PHP preg_replace everything but text in brackets

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.

You can do this:

$m = preg_replace ('/<span contenteditable="false" data-tag=\"/i','',$message);
$answer = preg_replace ('/\">.*?<\/span>/i', '' ,$m);

Is this what you're looking for?

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

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM