Из того, что я могу сказать, в то время как . NET regex engine - к которому PowerShell предоставляет доступ - позволяет использовать обратных ссылок (например, \1
) в обходные утверждения в принципе, это не работает в вашем сценарии, который сводится к этому упрощенному примеру:
# !! Does NOT match, even though 'foo foo' -match '(?<=foo )(foo)' does
PS> 'foo foo' -match '(?<=\1 )(foo)'
False
Предположительно , обратная ссылка в шаблоне lookbehind соответствует до группы захвата и, следовательно, ничего не соответствует (обратная ссылка на группу захвата, которая (еще) не захватила что-либо, никогда не совпадает); Придуманный пример, где он работает (группа захвата на первом месте):
'foo foo' -match '(foo) .*(?<=\1)$'
Следовательно, ваша попытка (которая по ошибке использует $Matches[1]
[ 1] вместо \1
) не работает.
Вы можете обойти эту проблему, выполнив две операции сопоставления в каждой строке: первая, чтобы захватить интересующую фразу, и вторая также ищет эту фразу в строке перед начальным соответствием (обратите внимание, что предполагается, что для регулярного выражения поиска фразы один соответствует строке).
# Array of input lines.
$lines = @'
<b><font color="#5b4636">mit ~ und <u>Kegel</u></font></b> <span class="Icon">hum</span> <span class="Icon">fam</span> with the whole family;<br>
<b><font color="#5b4636">aus ~ern werden <u>Leute</u></font></b> <span class="Icon">prov</span> children grow up [all too] quickly;<br>
<b><font color="#5b4636">das ~ muss einen <u>Namen</u> haben</font></b> it must be called something;<br>
<b><font color="#5b4636">das ~ beim [rechten] <u>Namen</u> nennen</font></b> to call a spade a spade;<br>
<b><font color="#5b4636">~er und <u>Narren</u></font></b> [<i><font color="black">o</font></i> <b><font color="#5b4636"><u>Betrunkene</u></font></b>] <b><font color="#5b4636">sagen die Wahrheit</font></b> (<i><font color="black">sagen die Wahrheit</font></i>) children and fools speak the truth <span class="Icon">prov</span><br>
<b><font color="#5b4636">kleine ~er, kleine <u>Sorgen</u>, große ~er, große Sorgen</font></b> (<i><font color="black">große ~er, große Sorgen</font></i>) children when they are little make parents fools, when great, mad [<i><font color="black">or</font></i> they are great they make them mad] <span class="Icon">prov</span><br>
<b><font color="#5b4636">kein ~ von <u>Traurigkeit</u> sein</font></b> <span class="Icon">sein</span> to be sb who enjoys life;<br>
<b><font color="#5b4636">ich bin kein ~ von Traurigkeit</font></b> I [like [<i><font color="black">or</font></i> know how] to] enjoy life;<br>
<b><font color="#5b4636">ein ~ seiner <u>Zeit</u> sein</font></b> to be a child of one's time;<br>
<b><font color="#5b4636">[ein] <u>gebranntes</u> ~ scheut das Feuer</font></b> once bitten, twice shy <span class="Icon">prov</span><br>
<b><font color="#5b4636">was Glücksspiele angeht, bin ich ein gebranntes ~!</font></b> I've learned my lesson as far as games of chance are concerned;<br>
<b><font color="#5b4636">bei jdm <u>lieb</u> ~ sein</font></b> <span class="Icon">fam</span> to be sb's favourite [<i><font color="black">or</font></i> blue-eyed boy] [<i><font color="black">or</font></i> girl];<br>
'@ -split '\r?\n' #'
foreach ($line in $lines) {
# Note: To better illustrate the result, the doubled phrase
# rather than a Boolean is printed.
if (
$line -match '(?<before>.*)\(<i><font color="black">(?<phrase>[^<]+)</font></i>\)'
-and
$Matches.before -match [regex]::Escape($Matches.phrase)
) {
$Matches[0]
}
}
Вышеуказанные значения (в строке 5 и 6 соответствуют удвоенным фразам):
sagen die Wahrheit
große ~er, große Sorgen
[1] automati c $Matches
переменная в PowerShell заполняется после операции регулярного выражения, чтобы отразить то, что было захвачено, и заполняется, только если совпадение завершилось успешно . Это просто функция PowerShell, о которой движок. NET regex (который -match
вызывает за кулисами) ничего не знает.
Встраивая $($Matches[1])
в расширяемую строку ( "..."
), который служит в качестве регулярного выражения, поэтому вы (a) расширяете это значение (заменяя ссылку на переменную на ее значение) до механизм регулярных выражений видит строку, и (b) ссылаются на то, что самая последняя предыдущая операция успешного сопоставления была захвачена в ее первой группе захвата.
Вкратце: единственный способ использовать обратные ссылки в PowerShell - это использовать синтаксис движка. NET regex; например, \1
для обозначения первой группы захвата.