Html DotAll和多行正则表达式
我在Powershell中使用Rexex有点麻烦。好像有一个安装错误或什么的 我想要处理的文本是一个html文件,如下所示(示例1): 还有这个Html DotAll和多行正则表达式,html,regex,powershell,powershell-3.0,Html,Regex,Powershell,Powershell 3.0,我在Powershell中使用Rexex有点麻烦。好像有一个安装错误或什么的 我想要处理的文本是一个html文件,如下所示(示例1): 还有这个 $x = $x -ireplace '(?ms)\[(.?){7}Mobile(.*?)\]', 'MyReplacement2' 基本上,[标记变量的开始,]标记变量的结束。由此产生两个问题: 因为我们有两个变量,mobile和fax,所以我使用(.?){7}来允许一些字符(这里是7个),并避免在第一个[nearmobile和最后一个]nearfa
$x = $x -ireplace '(?ms)\[(.?){7}Mobile(.*?)\]', 'MyReplacement2'
基本上,[标记变量的开始,]标记变量的结束。由此产生两个问题:
(.?){7}
来允许一些字符(这里是7个),并避免在第一个[nearmobile和最后一个]nearfax之间匹配孔部分(如果我使用(.*)
而不是(.?){7}
)。我不确定是否有其他选择,以便我可以在起始[和变量关键字“Fax”之间允许任何数量的字符(而不是7个字符)。这将有助于避免在添加
之类的内容时出现错误匹配(其中仅7个字符是不够的,就像我说的(.*)
将失败).希望我能解释清楚(有点难)-如果不能:请尽管问[移动:
%手机%|]电话:%telephone%[|传真:
%传真号码%]
DotAll模式的诀窍是使用[\s\s]
而不是
。此字符类匹配任何字符(因为它匹配空格和非空格字符)。(就像[\w\w]
或[\d\d]
一样,但空格似乎是一种惯例。)
要绕过7
,您可以简单地禁止在您真正想要匹配的之前关闭]
(顺便说一下,这也使得DotAll变得不必要)。所以像这样的东西对你来说应该很好:
\[([^\]:]*)Fax([^\]]*)\]
它看起来有点难看,但它的意思是:
\[ # literal [
( # capturing group 1
[^\]:]* # match as many non-:, non-] characters as possible
) # end of group 1
Fax # literal Fax
( # capturing group 2
[^\]]* # match as many non-] characters as possible
) # end of group 2
\] # literal ]
请注意,这些模式都不需要多行模式m
(您的和我的都不需要),因为它所做的只是分别使^
和$
匹配行的开头和结尾。但是没有一个模式包含这些元字符。因此修改器不做任何事情
我的控制台输出:
PS> $x = "<span>[Mobile: %mobile% |] Phone: %telephone% [| Fax: %faxNumber%]</span>"
PS> $x -ireplace '\[([^\]:]*)Mobile([^\]]*)\]', 'MyReplacement1'
<span>MyReplacement1 Phone: %telephone% [| Fax: %faxNumber%]</span>
PS> $x -ireplace '\[([^\]:]*)Fax([^\]]*)\]', 'MyReplacement2'
<span>[Mobile: %mobile% |] Phone: %telephone% MyReplacement2</span>
PS>$x=“[Mobile:%Mobile%|]电话:%telephone%[|传真:%faxNumber%]”
PS>$x-ireplace'\[([^\]]:]*)Mobile([^\]*)\]','MyReplacement1'
MyReplacement1电话:%telephone%[|传真:%faxNumber%]
PS>$x-ireplace'\[([^\]]:]*)传真([^\]*)\]','MyReplacement2'
[手机:%Mobile%|]手机:%telephone%MyReplacement2
感谢您的精彩回答。但仍然存在一些问题:非:匹配是为了什么?另外,在为我的两个Powershell命令运行该模式时,mobile很好地被替换,但[| Fax:%faxNumber%]没有被替换:-(.运行在线Rexex验证器,您的正则表达式似乎是正确的想法。@masi我添加了:
,以避免与潜在的某些[东西:%Fax%]匹配
。但是如果括号中出现的传真与您无关,您可以从字符类中删除冒号。我将再次检查我的答案是否适用于后一个示例。@masi-hm,它对我来说非常适用。(但是,我在第一个字符类中更改了方括号,但是对于您的输入字符串,它应该不会有什么不同;无论如何,请参见我的编辑)当您像下面这样导入字符串时,不要用一个内联字符串来分配$x,而是导入字符串:$mystring=Get Content-Path.\test.html
,其中test.html包含我刚刚添加到我的帖子中的内容(示例3),那么它就不起作用了。这似乎是个问题linebreak@masi似乎有这个问题的原因。Get Content
不会生成带换行符的字符串,而是为每行生成一个字符串,需要重新连接在一起,因此-ireplace
可以处理整个文件。是的,我已经看到了。请参阅我的对答案发表评论,我们在这里删除我们的评论;)
<span>[Mobile:
%mobile% |] Phone: %telephone% [| Fax:
%faxNumber%]</span>
\[([^\]:]*)Fax([^\]]*)\]
\[ # literal [
( # capturing group 1
[^\]:]* # match as many non-:, non-] characters as possible
) # end of group 1
Fax # literal Fax
( # capturing group 2
[^\]]* # match as many non-] characters as possible
) # end of group 2
\] # literal ]
PS> $x = "<span>[Mobile: %mobile% |] Phone: %telephone% [| Fax: %faxNumber%]</span>"
PS> $x -ireplace '\[([^\]:]*)Mobile([^\]]*)\]', 'MyReplacement1'
<span>MyReplacement1 Phone: %telephone% [| Fax: %faxNumber%]</span>
PS> $x -ireplace '\[([^\]:]*)Fax([^\]]*)\]', 'MyReplacement2'
<span>[Mobile: %mobile% |] Phone: %telephone% MyReplacement2</span>