用 xml 元素环绕文本位

我正在寻找一种基于正则表达式用 XML 节点动态包围文本部分的方法。

考虑下面的例子

<speak>The test number is 123456789, and some further block of text.</speak>

现在假设我有一个针对数字的正则表达式,可以有选择地用一个新标签将其包围,这样它就会变成:

<speak>The test number is <say-as interpret-as="characters">123456789</say-as>, and some further block of text.</speak>

我想过使用 DomDocument 来创建标签,但不确定替换部分。有什么建议吗?


白猪掌柜的
浏览 176回答 3
3回答

12345678_0001

这可以使用xsl:analyze-stringXSLT 2.0 中的指令方便地处理。例如,您可以定义规则:<xsl:template match="speak">&nbsp; <xsl:analyze-string select="." regex="\d+">&nbsp; &nbsp; <xsl:matching-substring>&nbsp; &nbsp; &nbsp; <say-as interpret-as="characters">&nbsp; &nbsp; &nbsp; &nbsp; <xsl:value-of select="."/>&nbsp; &nbsp; &nbsp; </say-as>&nbsp; &nbsp; </xsl:matching-substring>&nbsp; </xsl:analyze-string></xsl:template>

杨__羊羊

DOM 是正确的方法。它允许您查找和遍历文本节点。对这些节点的内容使用 RegEx 并将新节点构建为片段。function wrapMatches(\DOMNode $node, string $pattern, string $tagName, $tagAttributes = []) {&nbsp; &nbsp; $document = $node instanceof DOMDocument ? $node : $node->ownerDocument;&nbsp; &nbsp; $xpath = new DOMXpath($document);&nbsp; &nbsp; // iterate all descendant text nodes&nbsp; &nbsp; foreach ($xpath->evaluate('.//text()', $node) as $textNode) {&nbsp; &nbsp; &nbsp; &nbsp; $content = $textNode->textContent;&nbsp; &nbsp; &nbsp; &nbsp; $found = preg_match_all($pattern, $content, $matches, PREG_OFFSET_CAPTURE);&nbsp; &nbsp; &nbsp; &nbsp; $offset = 0;&nbsp; &nbsp; &nbsp; &nbsp; if ($found) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // fragments allow to treat multiple nodes as one&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $fragment = $document->createDocumentFragment();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach ($matches[0] as $match) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list($matchContent, $matchStart) = $match;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // add text from last match to current&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $fragment->appendChild(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $document->createTextNode(substr($content, $offset, $matchStart - $offset))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // add wrapper element, ...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $wrapper = $fragment->appendChild($document->createElement($tagName));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ... set its attributes ...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach ($tagAttributes as $attributeName => $attributeValue) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $wrapper->setAttribute($attributeName, $attributeValue);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ... and add the text content&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $wrapper->textContent = $matchContent;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $offset = $matchStart + strlen($matchContent);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // add text after last match&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $fragment->appendChild($document->createTextNode(substr($content, $offset)));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // replace the text node with the new fragment&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $textNode->parentNode->replaceChild($fragment, $textNode);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}$xml = <<<'XML'<speak>The test number is 123456789, and some further block of text.</speak>XML;$document = new DOMDocument();$document->loadXML($xml);wrapMatches($document, '(\d+)u', 'say-as', ['interpret-as' => 'characters']);echo $document->saveXML();

慕尼黑的夜晚无繁华

你可以使用preg_replace这样的东西:$str = '<speak>The test number is 123456789, and some further block of text.</speak>';echo preg_replace('/(\d+)/','<say-as interpret-as="characters">$1</say-as>',$str);输出将是:<speak>The test number is <say-as interpret-as="characters">123456789</say-as>, and some further block of text.</speak>
打开App,查看更多内容
随时随地看视频慕课网APP