2009-03-05 2 views
18

У меня есть текстовый файл, содержащий строки данных. Я могу использовать следующий Powershell скрипт для извлечения строк Я заинтересован в:Как вы извлекаете значение regex backreference/match в Powershell

select-string -path *.txt -pattern "subject=([A-Z\.]+)," 

Некоторые примеры данных будут:

blah blah subject=THIS.IS.TEST.DATA, blah blah blah 

То, что я хочу, чтобы иметь возможность извлекать только фактическое содержимое (т.е. строка «THIS.IS.TEST.DATA»). Я пробовал:

select-string -path *.txt -pattern "subject=([A-Z\.]+)," | %{ $_.Matches[0] } 

Но свойство «Совпадения» всегда равно нулю. Что я делаю не так?

ответ

9

Я не знаю, почему ваша версия не работает. Он должен работать. Вот уродливая версия, которая работает.

$p = "subject=([A-Z\.]+)," 
select-string -path *.txt -pattern $p | % {$_ -match $p > $null; $matches[1]} 

Редактировать. Объяснение DANT:

-match регулярный оператор выражениям:

>"foobar" -match "oo.ar" 
True 

> $null просто подавляет Правда записывается на выход. (Попробуйте удалить его.) Существует командлет, который делает то же самое, имя которого я не помню в данный момент.

$matches - волшебная переменная, которая содержит результат последней операции -match.

+0

спасибо, что работает, но не могли бы вы объяснить, что вы делаете? В частности, бит $ _ -match $ p> $ null. – d4nt

+1

Командлет dangph думает о «Out-Null». Но вы можете также отбросить всю строку до [void]: [void] ($ _ -match $ p) – JasonMArcher

2

Проблема с кодом, который вы вводите, заключается в том, что select-string не пропускает фактический объект Regex. Вместо этого он передает другой класс, называемый MatchInfo, который не имеет актуальной информации соответствия регулярных выражений.

Если вы хотите только один раз запустить регулярное выражение, вам придется свернуть свою собственную функцию, которая не слишком сложна.

function Select-Match() { 
    param ($pattern = $(throw "Need a pattern"), 
     $filePath = $(throw "Need a file path")) 
    foreach ($cur in (gc $filePath)) { 
    if ($cur -match $pattern) { 
     write-output $matches[0]; 
    } 
    } 
} 

gci *.txt | %{ Select-Match "subject=([A-Z\.]+)," $_.FullName } 
+0

Но почему свойство MatchInfo.Matches не работает? http://msdn.microsoft.com/en-us/library/microsoft.powershell.commands.matchinfo.matches(VS.85).aspx –

+0

@dangph, я считаю, что это ошибка в документах. Вы можете проверить это, запустив «gci a * .txt | gm». Получаемый тип не имеет свойства Matches. – JaredPar

+0

JaredPar, это не сработало для меня, но я считаю, что вы правы. Попробуйте следующее: «gm -inputobject (новый объект Microsoft.PowerShell.Commands.MatchInfo)». –

2

Еще один вариант

gci *.txt | foreach { [regex]::match($_,'(?<=subject=)([^,]+)').value } 
2

Научившись много от всех других ответов, которые я был в состоянии получить то, что я хочу, используя следующую строку:

gci *.txt | gc | %{ [regex]::matches($_, "subject=([A-Z\.]+),") } | %{ $_.Groups[1].Value } 

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

+0

Рад, что вы нашли решение. Я только что проверил v2, и свойство Matches работает с Select-String. Поэтому в будущем это будет менее болезненно для вас. :) – JasonMArcher

0

Другой вариант, соответствующий 7 цифр в строке

echo "123456789 hello test" | % {$_ -match "\d{7}" > $null; $matches[0]} 

возвращается: 1234567

4

In PowerShell V2 CTP3, свойство соответствий реализуется.Таким образом, следующие будут работать:

select-string -path *.txt -pattern "subject=([A-Z\.]+)," | %{ $_.Matches[0].Groups[1].Value } 
1

команда Выбрать струна, кажется, возвращает MatchInfo переменной, а не «строка» переменной. Я провел несколько часов, узнав об этом на форумах и официальном сайте, не повезло. Я все еще собираю информацию. способ обойти это объявить явно строковая переменная для хранения результата вернулся из Select-String, из вашего примера:

[строка] $ Foo = Select-String -path * .txt -pattern " subject = ([AZ.] +), "

Переменная $ foo теперь является строкой, а не объектом MatchInfo.

Надеюсь, это поможет.

ПС5 версия PowerShell 5 строковые строки манипуляции

Смежные вопросы