Как правильно построить RegEx для многострочных значений в reg файле - PullRequest
0 голосов
/ 14 января 2019

Я хотел бы получить значения из файла .reg (файл REG EXPORT), чтобы я мог сравнить их с другим файлом .reg. У меня проблемы с созданием RegEx для этого.

факты, которые усложняют мне задачу:

  1. Я не знаю, какие типы ключей реестра используются в файле (поэтому я хочу построить регулярное выражение для всех различных типов, таких как string, dword, qword, multistring, ...)
  2. Я не знаю, является ли последний символ в файле новой строкой или нет
  3. Я бы хотел вернуть только фактическое значение, например, fa,ad,df,fa,ad,df,fa,ad если regkey равен "qword"=hex(b):fa,ad,df,fa,ad,df,fa,ad
$Text = @'
[HKEY_LOCAL_MACHINE\SOFTWARE\Test]
"String"="asfasdfasasfasdfasasfasdfasasfas"
"Binary"=hex:d3,45,34,53,45,34,53,45,34,53,45,34,53,45,34,53,45,34,5b,09,89,08,\
34,09,8a,ef,02,30,40,9a,ad,fa,d0
"DWORD"=dword:fefefefe
"multistring"=hex(7):61,00,62,00,6c,00,61,00,73,00,66,00,62,00,00,00,62,00,61,\
  00,6c,00,73,00,66,00,62,00,61,00,73,00,64,00,66,00,00,00,62,00,61,00,6c,00,\
  73,00,64,00,66,00,61,00,64,00,6c,00,66,00,00,00,61,00,73,00,64,00,66,00,61,\
  00,73,00,64,00,66,00,00,00,61,00,73,00,64,00,66,00,00,00,61,00,73,00,64,00,\
  00,00,66,00,61,00,73,00,64,00,00,00,66,00,61,00,73,00,64,00,66,00,61,00,73,\
  00,66,00,61,00,73,00,64,00,66,00,00,00,61,00,73,00,64,00,66,00,61,00,73,00,\
  64,00,66,00,61,00,73,00,64,00,00,00,61,00,73,00,64,00,66,00,61,00,73,00,64,\
  00,66,00,00,00,00,00
"qword"=hex(b):fa,ad,df,fa,ad,df,fa,ad
'@

# this one works
$key = "multistring"
$regex = ('(?ms)\"{0}\"=hex\(7\):(.+)\n' -f [RegEx]::Escape($key))
[regex]::Matches($Text, $regex) | foreach { $_.Groups[1].Value }

# this one does not work because there is no newline after the last line...
$key2 = "qword"
$regex2 = ('(?ms)\"{0}\"=hex\(b\):(.+)\n' -f [RegEx]::Escape($key2))
[regex]::Matches($Text, $regex2) | foreach { $_.Groups[1].Value } 

Ответы [ 2 ]

0 голосов
/ 14 января 2019

В своем регулярном выражении вы используете (?s), который является модификатором , который заставит точку соответствовать любому символу, включая новые строки. Таким образом, .+ будет соответствовать до конца всех строк.

Вы можете использовать группу захвата для захвата части после двоеточия. Сначала сравните часть до двоеточия, используя \"{0}\"=hex\(7\):

Затем сопоставьте то, что следует до конца строки, и используйте отрицательный прогноз, чтобы проверить, не является ли то, что следует, строкой, начинающейся со слова между двойными кавычками, за которым следует знак равенства, например «qword» =. Пока это так, сопоставьте всю строку.

Ваш код может выглядеть следующим образом:

$regex = \"{0}\"=hex\(7\):(.*(?:(?!\n"[^\n"]+"=)\n.*)*)

Объяснение второй части:

  • ( Захват группы, которая будет держать вашу ценность
    • .* Соответствует любому символу, кроме новой строки 0+ раз
    • (?: Группа без захвата
      • (?! Отрицательный взгляд на то, что следует, не
        • \n"[^\n"]+"= Соответствует \n", отрицается класс символов , чтобы не совпадать ни с одним из \n или "
      • )\n.* Закрыть отрицательный прогноз и сопоставить \n, за которым следует любой символ, кроме новой строки 0+ раз
    • )* Закрыть группу без захвата и повторить 0+ раз
  • ) Закрыть группу захвата

Пример шаблона

\"multistring\"=hex\(7\):(.*(?:(?!\n"[^\n"]+"=)\n.*)*)

Regex demo

0 голосов
/ 14 января 2019

.+ является жадным выражением, а модификатор (?s) делает . совпадение всех символов (включая символы новой строки), поэтому (.+)\n будет сопоставлять все до последней новой строки.

Попробуйте что-то вроде этого:

$regex = '"{0}"=hex\(b\):(.+(?:\n  .+)*)'

Вам не нужно ни (?m), ни (?s) здесь, потому что вы не хотите, чтобы . включал переводы строк, и вы не хотите сопоставлять начало или конец строк внутри многострочной строки. .+(?:\n .+)* соответствует остатку строки после префикса hex(b): и всем последующим строкам, начинающимся с двух последовательных пробелов. (?:...) - это просто группа без захвата, поскольку нет необходимости фиксировать каждую строку в отдельной группе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...