我有这个文本文件:
[Tabs]
MAILBOXSEND=1
MAILBOX=8
USERS=6
DOCUMENTS_Q=9
MED_WEBSERVCALLS_LOA=3
FCLMNA=1
INCZOOMFORM=1
USERSB=1
USERSB_ONE=1
DATAPRIV=1
MED_WEBSERVCALLS=2
TINVOICES=1
PORDERS=9
PORDERSTOTAL=1
LOGPART=1
LOGCOUNTERS=1
PARTMSG=1
[External Mail]
Send=Y
Hostname=Server
Domain=Domain
Myemail=My@email.com
MyName=My Test
Port=25
SSL=0
[Search]
SUPPLIERS=5,1
StartButton=1
Ignore Case=0
PART=6,1
我试图捕捉[External Mail]
到下一个[]
括号组之间的所有文字,
我有这个正则表达式完成这项工作并在Regex101中进行了测试,经过所有测试后我发现它在PowerShell中没有工作:
$Text = Get-Content c:\text.txt
$Text -match '(?s)(?<=\[External Mail\]).*?(?=\[.*?\])'
or:
$Text | Select-String '(?s)(?<=\[External Mail\]).*?(?=\[.*?\])'
没有回归
你知道我错过了什么吗?
由于
答案 0 :(得分:4)
看起来你正在解析.INI文件。不要试图再次发明轮子,从existing code开始利用。此解决方案将.Ini文件读取为易于使用的嵌套哈希表。
如果链接腐烂,这里是Scripting Guys存档的功能:
function Get-IniContent ($filePath)
{
$ini = @{}
switch -regex -file $FilePath
{
"^\[(.+)\]" # Section
{
$section = $matches[1]
$ini[$section] = @{}
$CommentCount = 0
}
"^(;.*)$" # Comment
{
$value = $matches[1]
$CommentCount = $CommentCount + 1
$name = "Comment" + $CommentCount
$ini[$section][$name] = $value
}
"(.+?)\s*=(.*)" # Key
{
$name,$value = $matches[1..2]
$ini[$section][$name] = $value
}
}
return $ini
}
# Sample usage:
$i = Get-IniContent c:\temp\test.ini
$i["external mail"]
Name Value
---- -----
Domain Domain
SSL 0
Hostname Server
Send Y
MyName My Test
Port 25
Myemail My@email.com
$i["external mail"].hostname
Server
答案 1 :(得分:3)
由于您尝试获取多行正则表达式匹配,因此您需要针对单个多行字符串进行操作。这是你的两个regex101和PowerShell案例之间的区别。 Get-Content
将返回一个字符串 array 。你的正则表达式没有匹配任何东西,因为它只是在文件中的单行上进行测试。
PowerShell 2.0
$Text = Get-Content c:\text.txt | Out-String
PowerShell 3.0更高
$Text = Get-Content c:\text.txt -Raw
正如我在评论中所说的那样,对于这种类型的字符串提取,你真的不需要正则表达式。 There are scripts that already exist to parse INI content。如果您打算替换内容,则必须找到合作伙伴cmdlet Out-INIContent
,假设它存在,但我确信有人成功了。 vonPryz's answer包含有关cmdlet的更多信息