Найдите переменные вхождения% string в документе и замените их суффиксом. % string .prefix, но не href, когда он найден как часть URL - PullRequest
1 голос
/ 28 января 2020

Я отправлю тексты в Google Translate, но в строках есть переменные, которые не могут быть переведены.

Поэтому я должен добавить к ним суффикс и префикс.

Но сделайте ничего, если они находятся в 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); }

Я прочитал об отрицательной обратной ссылке, чтобы попытаться отфильтровать совпадения внутри. но есть обратное отслеживание aut-back -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, $prefix.'$0'.$suffix, $text); 

Очень уродливо это соответствует! foobar и не должно быть в href = "/ someurl / ! foobar / word"
Pro:

  1. Это соответствует! *,% *, @ * , {*} и {*}. *
  2. Работает с preg_filter ($ p, $ prefix. '$ 0'. $ суффикс, $ text);
  3. Отображает выходные данные с несопоставленными части нашего поиска и замены модификаций.

Con:

  1. Очень, очень некрасиво,
  2. Добавить префикс и суффикс в href которые полностью ломаются html семанти c.

Метод 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);

Это выглядит обещая, что он соответствует всем, включая href в группе 1, но затем сопоставляет только те переменные, которые нам нужны вне Pro:

  1. Группа 0 соответствует первой половине якорей (части, содержащей href) и т. д. *,% *, @ *, {*} и {*}. * * 106 0 *
  2. Группа 1 точно соответствует префиксу и суффиксу, который мы хотим

Con:

  1. это выглядит так Решение не работает с preg_filter, который переносил входную строку в измененную выходную строку с изменениями. ...

    Текущее предложение по решению.

  2. Как go иметь массив 2 и иметь измененную совпадающую строку.

  3. Возможно, с использованием PREG_OFFSET_CAPTURE. со смесью offset + strlen и с учетом смещения совпадения и длины (префикс. $ match.suffix).
  4. Создайте функцию, которая перемещается назад в массиве с учетом смещения последнего совпадения , затем вставьте его на место, затем go вернитесь к предыдущим совпадениям, вставьте де-модификацию с этим смещением и проследите массив таким образом.

Говорят, что предпочтительнее использовать 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();  } 

1 Ответ

1 голос
/ 29 января 2020

Вы можете попробовать это:

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

Объяснение:

Я использовал \ K, чтобы отменить предыдущий матч, поэтому не нужно было беспокоиться о негативе смотреть за. Однако \ K соответствует пустому курсору. Для этого я предоставил альтернативное решение. Вы получаете это в php источнике.

Regex 101 Sample

php source запустите его :

$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;
...