我将文本发送到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”
专业版:
- 它匹配!*,%*,@ *,{*}和{*}。*
- 使用preg_filter($ p,$ prefix。'$ 0'。$ suffix,$ text);
- 它使用搜索和替换修改中不匹配的部分来呈现输出。
缺点:
- 非常难看,
- 在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之外我们想要的变量:
- 第0组匹配锚的前半部分(包含href的部分),因此!*,%*,@ *,{*}和{*}。*
- 第1组完全匹配我们要添加的前缀和后缀
缺点:
-
看起来此解决方案不适用于preg_filter,preg_filter会将输入字符串修改后保留到更改后的输出字符串中。 ...
当前解决方案建议。
-
如何从具有第2组数组和具有修改的匹配字符串开始。
- 可能使用PREG_OFFSET_CAPTURE。结合使用offset + strlen并考虑匹配的偏移量和长度(前缀。$ match.suffix)。
- 制作一个函数,以最后一个匹配的偏移量在数组中向后移动,然后将其插入到位,然后返回到先前的匹配,在该偏移量处插入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(); }