我试图从日志文件中提取一些文本,但我遇到了问题。 我正在处理的示例文本是:
ahksjhadjsadhsah
sakdsjakdjks
ksajdksaj
REF=35464
sadsad
213213
213
2
13
我需要提取价值" 35464" (REF编号)。我对正则表达式的了解有限,但想到了REF =([0-9] +)'会这样做。
现在我不确定读这个文件的效果如何,所以我尝试了几种方法:
select-string -path e:\powershell\log.txt -pattern 'REF=([0-9]+)' | % { $_.Matches } | % { $_.Value }
这给了我" REF = 35464" - 我不明白(为什么REF =包括在内),因为我认为'捕获'只是()'中的部分?
我也尝试过:
$data=Get-Content e:\powershell\log.txt
$data -match 'REF=([0-9]+)'
$Matches
但是$ Matches是空的。
我也尝试了类似于上面的方法,但是逐行,例如:
foreach ($line in $data)
{
$line -match 'REF=([0-9]+)'
}
我要么没有匹配,要么完全匹配(包括REF =部分)。我也尝试过小组(即'(REF =)([0-9] +)'),我无法得到我需要的东西。
我该如何阅读文件?我的正则表达式出了什么问题?
我只需将此提取的值作为可用变量。
答案 0 :(得分:1)
可能是您尝试访问捕获组的方式
我将这个快速静态类放在一起,以说明如何获得您正在寻找的匹配。
注意:我正在使用正则表达式上的@符号和输入字符串来使它们成为文字。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace SkunkWorks.RegexPractice
{
public static class RegexPractice2
{
public static string input = @"ahksjhadjsadhsah
sakdsjakdjks
ksajdksaj
REF=35464
sadsad
213213
213
2
13";
static string pat = @"REF=([0-9]+)";
public static void Do()
{
Regex r = new Regex(pat, RegexOptions.IgnoreCase);
Match m = r.Match(input);
int matchCount = 0;
while (m.Success)
{
Console.WriteLine("Match" + (++matchCount));
for (int i = 1; i <= 2; i++)
{
Group g = m.Groups[i];
Console.WriteLine("Group" + i + "='" + g + "'");
CaptureCollection cc = g.Captures;
for (int j = 0; j < cc.Count; j++)
{
Capture c = cc[j];
System.Console.WriteLine("Capture" + j + "='" + c + "', Position=" + c.Index);
}
}
m = m.NextMatch();
}
}
}
}
答案 1 :(得分:0)
当我需要从字符串数组中提取子字符串时,我通常会使用在$Matches
语句中使用-match
运算符生成的自动变量Where
。像这样:
$Data | Where{$_ -match "REF=([0-9]+)"} | ForEach{$Matches[1]}
现在,$Matches
变量将有一个数组。第一个条目将是它匹配的整行,第二个对象将只是捕获的文本,这就是我指定[1]
的原因。现在,关于您正在匹配的RegEx ......技术上它是可以接受的,但它不是非常具体,所以它真的可以返回自[0-9]+
以来的第一个数字属于[0-9]
范围的1个或多个字符。如果您想确保获得所有数字,可以通过在匹配中使用行尾字符$
来告诉它将所有内容放到行尾:REF=([0-9]+)$
。我们无法确定数字后面是否有任何空格,因此您可能也希望使用\s
符号来查找任何空白字符(空格,制表符,等等) ,并使用后面的星号,这意味着零或更多。然后它变成REF=([0-9]+)\s*$
,它可以让你完全找到你想要的东西。最后,我会使用\d
而不是[0-9]
,因为它做同样的事情,而且它更短更简单,专门为工作而做。所以,我们有:
$Data | Where{$_ -match "REF=(\d+)\s*$"} | ForEach{$Matches[1]}
这是逐步细分的,并在此解释:https://regex101.com/r/dG7jC7/1