регулярное выражение: сопоставление и замена всех адресов X400 (разделенных точкой с запятой) в строке других объектов, разделенных точкой с запятой

#regex #powershell

#регулярное выражение #powershell

Вопрос:

Я пытаюсь проанализировать экспорт моего корпоративного каталога, и у меня возникли проблемы из-за обработки экспорта с запятой. Каждая строка экспортируемых данных содержит различимое имя пользователя, а затем один или несколько адресов электронной почты (sip, smtp, x400), связанных с этим пользователем. Я пытался определить регулярное выражение, которое я мог бы использовать для сопоставления всех адресов x400 в строке, а затем заменить точки с запятой в адресе x400 запятыми. Адрес x400 отображается в этом формате x400:c=us;a= ;p=company;o=Exchange;s=lastName;g=firstName; . Замена точек с запятой только в адресе X400 даст мне строку с правильными разделителями, поэтому я мог бы использовать скрипт для дальнейшего анализа данных. Вот мои данные экспорта:

 CN=Doe\, Jane,OU=Employee,OU=Production,OU=Users,DC=COMPANY,DC=LOC;sip:jdoe@company.com;smtp:jdoe@company-b.com;smtp:Jane.Doe@company.com;SMTP:JDoe@company.com;X400:c=us;a= ;p=Company;o=Exchange;s=Doe;g=Jane;
CN=Smith\, Mike,OU=Employee,OU=Production,OU=Users,DC=COMPANY,DC=LOC;sip:msmith@company.com;x400:c=us;a= ;p=COMPANY;o=Exchange;s=Smith;g=Mike;;smtp:MSmith@company-b.com;smtp:Mike.Smith@company.com;X400:c=us;a= ;p=COMPANY;o=Exchange;s=Smith;g=Mike;;SMTP:msmith@compnay.com;smtp:MmSmith@company.com;smtp:Mike.Smith@company.com;smtp:MSmith@company-b.com;smtp:Mike.Smith@company.com
CN=Jones\, Barbara,OU=Employee,OU=Production,OU=Users,DC=COMPANY,DC=LOC;BJones@company.com;SMTP:BRJoenes@company.com;sip:BrJoes@company.com
CN=Bay\, Matt,OU=Employee,OU=Production,OU=Users,DC=COMPANY,DC=LOC MBay@company.com;sip:MBay@company.com
CN=O'Connor\, Sam,OU=Visitor,OU=Production,OU=Users,DC=COMPANY,DC=LOC;sip:SO'Connor@company.com;x400:c=us;a= ;p=COMPANY;o=Exchange;s=O'Connor;g=Sam;;so'connor@company-b.com
  

Я ищу замену регулярного выражения, которая приведет к тому, что данные экспорта будут выглядеть следующим образом…

 CN=Doe\, Jane,OU=Employee,OU=Production,OU=Users,DC=COMPANY,DC=LOC;sip:jdoe@company.com;smtp:jdoe@company-b.com;smtp:Jane.Doe@company.com;SMTP:JDoe@company.com;X400:c=us,a= ,p=Company,o=Exchange,s=Doe,g=Jane,;
CN=Smith\, Mike,OU=Employee,OU=Production,OU=Users,DC=COMPANY,DC=LOC;sip:msmith@company.com;x400:c=us,a= ,p=COMPANY,o=Exchange,s=Smith,g=Mike,;smtp:MSmith@company-b.com;smtp:Mike.Smith@company.com;X400:c=us,a= ,p=COMPANY,o=Exchange,s=Smith,g=Mike,;SMTP:msmith@compnay.com;smtp:MmSmith@company.com;smtp:Mike.Smith@company.com;smtp:MSmith@company-b.com;smtp:Mike.Smith@company.com
CN=Jones\, Barbara,OU=Employee,OU=Production,OU=Users,DC=COMPANY,DC=LOC;BJones@company.com;SMTP:BRJoenes@company.com;sip:BrJoes@company.com
CN=Bay\, Matt,OU=Employee,OU=Production,OU=Users,DC=COMPANY,DC=LOC MBay@company.com;sip:MBay@company.com
CN=O'Connor\, Sam,OU=Visitor,OU=Production,OU=Users,DC=COMPANY,DC=LOC;sip:SO'Connor@company.com;x400:c=us,a= ,p=COMPANY,o=Exchange,s=O'Connor,g=Sam,;so'connor@company-b.com
  

Я использую регулярное выражение PowerShell.

Ответ №1:

Замена точек с запятой только в адресе X400 даст мне строку с правильными разделителями, поэтому я мог бы использовать script для дальнейшего анализа данных.

Вы также можете просто учитывать формат X400 при анализе данных:

 Get-Content data.txt |ForEach-Object {
    $DN,$AddressString = $_ -split ';',2

    New-Object psobject -Property @{
        DistinguishedName = $DN
        Addresses = $AddressString -split ';(?=w :)'
    }
}
  

Ответ №2:

Используйте что-то вроде этого:

 ... -replace 'x400:([a-z]*=.*?\;)*(;|$)'
  

Комментарии:

1. Ansgar, ваше предложение, похоже, работает, если в строке есть только одна запись x400, но если их две, как в примере «Майк Смит», похоже, что они не совпадают для них обоих. Есть ли у вас какие-либо предложения о том, как можно определить регулярное выражение, чтобы оно совпадало со всеми адресами x400?

2. Мой первоначальный ответ не охватывал адреса X.400 в конце строки (что теперь исправлено). Кроме этого, он удалит любой адрес X.400, присутствующий в строке. Если это не работает для вас: пожалуйста, предоставьте доказательства.

Ответ №3:

Я бы использовал регулярное выражение для замены подстроки:

 $callback = {  
    Param
    (
        $match
    ) 

    '{0}' -f ($match.Groups[1].Value -replace ';', ',')
}

$txt = 'CN=Doe\, Jane,OU=Employee,OU=Production,OU=Users,DC=COMPANY,DC=LOC;sip:jdoe@company.com;smtp:jdoe@company-b.com;smtp:Jane.Doe@company.com;SMTP:JDoe@company.com;X400:c=us;a= ;p=Company;o=Exchange;s=Doe;g=Jane;'

$rex = [regex]'(X400:.*?g=. ?\)'
$rex.Replace($txt, $callback)
  

Комментарии:

1. Мартин, ваше предложение отлично работает, когда в строке есть один адрес x400, но если их несколько, например, в моем примере «Майк Смит», это, похоже, не работает. Есть ли способ сопоставить регулярное выражение для обоих адресов x400, а затем обработать их по отдельности с помощью $match ?

2. Конечно, это потому, что один адрес использует X и один x. Поэтому просто измените регулярное выражение на : ([X|x]400:.*?g=. ?\)