Захватите регулярное выражение для замены из таблицы поиска - PullRequest
0 голосов
/ 13 декабря 2018

Я пишу интерпретатор языка в PowerShell (язык PILOT, для тех, кто может быть заинтересован), и я дошел до того, что я реализую замену переменных.Имя переменной состоит из $ или #, за которым следует до десяти символов в наборе [A-Za-z0-9].Однако если перед именем переменной стоит \, ее следует заменить , а не .Насколько я могу судить, шаблон, который я ищу, соответствует [^\\][\$#]\w{,10}, но я не совсем понимаю, как сохранить результат соответствия в переменной PowerShell, чтобы я мог найти имя переменной втаблицу, чтобы заменить его значением.

Например, если переменная powershell $expr содержит строку \#Foo has the value #Foo, а $vartable["#Foo"] содержит значение 5, мне нужно будет захватить #Foo- только второй - в $ varname, а затем выполнить замену захваченного #Foo на $ vartable [$ varname] - $expr -replace "[^\\][\$#]\w{,10}",$vartable[$varname] должно дать \#Foo has the value 5.

Правильно ли я рассчитал шаблони как мне зафиксировать совпадение?

(Должен заметить, что я разрабатываю это с PowerShell 5.1, но ожидаю, что он сможет работать в этой версии или что-то еще позже, включая PSCore на не-Windowsоперационки.)

1 Ответ

0 голосов
/ 14 декабря 2018

Шаблон [^\\] - , обычно - недопустимый способ проверить, экранирован ли символ или нет, так как экранирование может также быть экранировано для обозначения буквенного символа обратной косой черты.Например, \\#Foo имеет переменную без экранирования, которая должна соответствовать исходным требованиям.Допустимый способ - использовать (?<=(?<!\\)(?:\\{2})*) .NET-совместимый внешний вид, который соответствует местоположению, которому непосредственно предшествует любое количество четных обратных косых черт, которым не предшествует обратная косая черта.

Далее, вы не можете использовать код внутри шаблона замены строки,Вы можете использовать обратный вызов внутри [regex]::Replace или - начиная с PowerShell Core v6.1 - вы можете использовать блок сценария в качестве аргумента замены для -replace:

[regex]::Replace($s,'(?<=(?<!\\)(?:\\{2})*)[$#]\w{1,10}\b', {param($match) $vartable[$match.Value] })

или (PowerShell Core v6.1 +):

$s -replace '(?<=(?<!\\)(?:\\{2})*)[$#]\w{1,10}\b', { $vartable[$_.Value] }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...