给出类似
的字符串一些文本和[A〜Token]以及更多文本和[not token]和 [另一个〜令牌]
我需要提取“令牌”以供以后替换。 令牌被定义为两个标识符,它们之间用〜隔开,并用[]括起来。我一直在使用$string -match "\[.*?~.*?\]"
,它可以正常工作。而且,据我所知,我正在将两个方括号转义,将任何字符重复零次或多次并强制延迟,然后再进行〜,然后对任何字符序列进行相同。因此,我的第一个改进是将.*?
替换为.+?
,因为我想要一个或多个,而不是零或多个。然后,我移至$string -match "\[[A-Za-z0-9]+~[A-Za-z0-9]+\]"
,它将两个标识符限制为字母数字,这是一个很大的改进。
因此,第一个问题是:
最后一种解决方案是最好的方法,还是有待进一步改进?
此外,当前我只返回一个令牌,因此我遍历字符串,替换找到的令牌,并循环直到没有令牌。但是,我的理解是RegEx在默认情况下是贪婪的,因此我希望最后一个版本返回两个令牌,并且我可以遍历字典而不是使用While循环。 因此,第二个问题是: 我只回来一场比赛,这是什么意思?还是我误解了贪婪匹配的工作原理?
编辑: 澄清一下,我使用的是$ matches,如下所示,但仍然只能得到1。
if ($string -match "\[[A-Za-z0-9]+~[A-Za-z0-9]+\]") {
Write-Host "new2: $($matches.count)"
foreach ($key in $matches.keys) {
Write-Host "$($matches.$key)"
}
}
此外,在识别令牌时,我真的不能使用直接替换,因为存在大量潜在替换。我拿令牌,去掉方括号,然后在〜上分割,以得到前缀和后缀值,然后确定一个特定的替换值,我可以使用专用的-replace来完成。 最后澄清一下,令牌的数量是可变的。它可以是一个,也可以是三个或四个。所以我的解决方案必须非常灵活。
答案 0 :(得分:2)
要列出所有标记并使用值,可以使用如下代码:
$matces = Select-String '\[([\w]+)~([\w]+)\]' -input $string -AllMatches | Foreach {$_.matches}
foreach($value in $matces){
$fullToken = $value.Value;
$firstPart = $value.Groups[1].Value;
$secondPart = $value.Groups[2].Value;
echo "full token found: '$fullToken' first part: '$firstPart' second part: '$secondPart'";
}
在与()
分组的正则表达式部分中注意,这允许访问令牌的某些部分。
在此循环中,您可以使用fullToken
和firstPart
找到要插入而不是secondPart
的适当值。
至于\[.*?~.*?\]
不能正常工作,因为它试图匹配并以文本[not a token] and [another~token]
成功,因为在此正则表达式中,标记部分允许字符][
。 \[[^\]\[]*?~[^\]\[]*?\]
(^
可以使表达式取反,因此它将显示为:][
以外的所有字符)也可以,但是如果\w
足够好,则不能用大括号读取我们吧。
答案 1 :(得分:0)
您可以使用\w
来匹配单词字符(字母,数字,下划线)。
结果就是模式\[\w+~\w+\]
。
现在,您可以使用该模式创建一个正则表达式对象:
$rgx = [Regex]::new($pattern)
,并使用Replace
运算符替换该模式的所有出现次数:
$rgx.Replace($inputstring, $replacement)
也许值得一提的是,正则表达式有一个.Match
运算符,它返回模式的第一个出现位置,还有一个.Matches
运算符,它返回该模式的所有出现位置。
答案 2 :(得分:0)
以示例行
$String = "Some text and [A~Token] and more text and [not a token] and [another~token]"
此RegEx带有捕获组
$RegEx = [RegEx]"\[(\w+~\w+)\][^\[]+\[[^\]]+\][^\[]+\[(\w+~\w+)\]"
if ($string -match $RegEX){
"First token={0} Second token={1}" -f $matches[1],$matches[2]
}
返回:
First token=A~Token Second token=another~token
请参见上面的https://regex101.com/r/tp6b9e/1
中解释的RegEx两个标记之间的区域与否定类交替匹配
[
/ ]
和文字char [
/ ]