在文档中查找%string的变量出现并用后缀替换。作为Url的一部分时,%string .prefix但不是href

我将文本发送到Google翻译,但字符串中有一些无法翻译的变量。

所以我必须给它们添加后缀和前缀。

但是如果它们在锚href的URL内,则什么也不做。

变量的可能格式为:

@foo !bar %foobar {foobar} {foo}.bar !bar_baz %foo-baz

来源:

> Hello Bob @foo <a href="/someurl/!foobar/!bar/word"> Word {foobar} </a> %foo someword !bar_baz

预期结果

> Hello Bob <span class="notranslate">@foo<\span> <a href="/someurl/!foobar/!bar/word"­> Word <span class="notranslate">{foobar}<\span> </a> <span class="notranslate">%foo<\span> someword <span class="notranslate">!bar_baz<\span>

我制作了一个非常丑陋的正则表达式来匹配变量,并添加后缀和前缀

function PregAddprefixSuffix($text){
      $pregpattern = '/(?<!href=\\")\{[a-zA-Z_0-9]+\}(\.\w+)?|(?<!href=\\")\%[a-zA-Z_0-9\-\w]+|(?<!href=\\")\@[a-zA-Z_0-9\-\w]+|(?<!href=\\")\#[a-zA-Z_0-9\-\w]+|(?<!href=\\")\![a-zA-Z_0-9\-\w]+/';
      $prefix = '<span class="notranslate">';
      $suffix = '</span>';
$result= preg_filter($pregpattern,$prefix.'$0'.$suffix,$text); }

我已阅读有关否定反向引用的内容,以尝试过滤掉其中的匹配项。但是如果我理解的话,就会出现自动回溯-13个字符的缺点。在我尝试过的Regx模式和功能及其缺点下。

方法1:

 $p ='/(?<!href=\\")\{[a-zA-Z_0-9]+\}(\.\w+)?|(?<!href=\\")\%[a-zA-Z_0-9\-\w]+|(?<!href=\\")\@[a-zA-Z_0-9\-\w]+|(?<!href=\\")\#[a-zA-Z_0-9\-\w]+|(?<!href=\\")\![a-zA-Z_0-9\-\w]+/';
 preg_filter($p,$text); 

非常难看,它与!foobar匹配,并且不应放在href =“ / someurl / !foobar / word”
专业版:

  1. 它匹配!*,%*,@ *,{*}和{*}。*
  2. 使用preg_filter($ p,$ prefix。'$ 0'。$ suffix,$ text);
  3. 它使用搜索和替换修改中不匹配的部分来呈现输出。

缺点:

  1. 非常难看,
  2. 在href内添加前缀和后缀,以完全破坏html 语义。

方法2:

https://www.phpliveregex.com/p/uNB

$p = '/(?:<a.*?\\">)|([\@|\!|\#|\%|\{][a-zA-Z_0-9\-\w]*[\}]?([\}]?[\.][\w]*)?)/';
preg_match_all($p,$input_lines,$output_array)
 print_r($output_array);

这看起来很有希望,它将匹配第1组中的所有href,但随后仅匹配Pro之外我们想要的变量:

  1. 第0组匹配锚的前半部分(包含href的部分),因此!*,%*,@ *,{*}和{*}。*
  2. 第1组完全匹配我们要添加的前缀和后缀

缺点:

  1. 看起来此解决方案不适用于preg_filter,preg_filter会将输入字符串修改后保留到更改后的输出字符串中。 ...

    当前解决方案建议。

  2. 如何从具有第2组数组和具有修改的匹配字符串开始。

  3. 可能使用PREG_OFFSET_CAPTURE。结合使用offset + strlen并考虑匹配的偏移量和长度(前缀。$ match.suffix)。
  4. 制作一个函数,以最后一个匹配的偏移量在数组中向后移动,然后将其插入到位,然后返回到先前的匹配,在该偏移量处插入de修改,然后以这种方式遍历数组。 li>

据说最好使用dom来操纵HTML,我并不反对。 但是,然后我如何找到多个通配符变量,例如:'![a-zA-Z_0-9\-\w]+',然后将后缀前缀添加到找到的匹配字符串中,而不是在href中不匹配?

我正在使用https://github.com/scotteh/php-dom-wrapper以便从响应中删除span元素

function fixspan($text) {
$doc = new \DOMWrap\Document();
$doc->html($text);
$nodesem = $doc->find('em.notranslate')->contents()->unwrap();
$nodesspan = $doc->find('span.notranslate')->contents()->unwrap();
return $doc->find('body > p')->contents();  } 
shz832003dky 回答:在文档中查找%string的变量出现并用后缀替换。作为Url的一部分时,%string .prefix但不是href

您可以尝试以下方法:

<a href[^>]*(?:(?:@|!|%|#)\w+|\{\w+\})[^>]*>\K|((?:@|!|%|#)\w+|\{\w+\})

说明:

我已经使用\ K否定了之前的比赛,因此不需要费心寻找负面观察。但是\ K匹配一个空光标。为此,我提供了替代解决方案。您可以在php源代码中得到它。

Regex 101 Sample

php源run it

$re = '/<a href[^>]*(?:(?:@|!|%|#)\w+|\{\w+\})[^>]*>\K|((?:@|!|%|#)\w+|\{\w+\})/m';
$str = 'Hello Bob @foo <a href="/someurl/!foobar/!bar">Word {foobar} </a> #foo someword #bar
<a href="/abc/d>koramamam</a>';
$subst = '<span class="notranslate">$1<\\\\span>';

$result = preg_replace('/<span class="notranslate"><\\\\span>/m',"",preg_replace($re,$subst,$str));

echo $result;
本文链接:https://www.f2er.com/2700115.html

大家都在问