DotAll和多线RegEx

时间:2012-12-02 21:43:50

标签: html regex powershell powershell-v3.0

我在Powershell中使用Rexex时遇到了一些麻烦。似乎存在致命错误或其他原因。

我想要使用的文本是一个html文件,如下所示(Example1):

<span>[Mobile: %mobile% |] Phone: %telephone% [| Fax: %faxNumber%]</span>
<Span>

问题是,由html编辑引起的,我也可能会得到这样的结果(例2):

<span>[Mobile: 

%mobile% |] Phone: %telephone% [| Fax: &nbsp;&nbsp;%faxNumber%]</span>

如您所见,我们获得了换行符和html转义,修复了空格&nbsp;

我的Powershell Regex看起来像这样:

$x = $x -ireplace '(?ms)\[(.?){7}Fax(.*?)\]', 'MyReplacement1'

和这个

$x = $x -ireplace '(?ms)\[(.?){7}Mobile(.*?)\]', 'MyReplacement2'

基本上 [标记变量的开头,] 结束。由此产生两个问题:

  1. 由于我们有两个变量,移动和传真,我使用(.?){7}允许SOME(这里是exacly 7)字符并避免匹配第一个[near Mobile < / strong> 最后一个]在传真 附近(如果我使用的是(.*?)而不是(.?){7},则会发生这种情况)。我不确定是否有替代方案,以便我可以在起始[和变量关键字“传真”之间允许任何数字(而不是7)字符。当添加&nbsp;&nbsp;之类的东西(其中只有7个字符不够,就像我说(.*?)会失败时)这样可以避免错配。希望我能够解释它(有点难) - 如果没有:请随意提问!
  2. Powershells -replace方法不提供设置正则表达式选项的方法,因此我必须使用(?ms)来设置DotAll和多行模式。如你所见,我在我的正则表达式模式中使用它。但是:添加换行符后,移动 %移动%之间的 ,如您在示例2 中看到的那样,正则表达式失败,什么都没有被替换!
  3. 我很乐意为专业人士提供任何帮助甚至正则表达式的建议,以避免我现在没有考虑的任何进一步问题......

    编辑: (示例3):

    <span>[Mobile: 
    
    %mobile% |] Phone: %telephone% [| Fax: 
    %faxNumber%]</span>
    

1 个答案:

答案 0 :(得分:8)

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 ]

Further reading on character classes.

请注意,这些模式都不需要多线模式m(既不是你的模式也不是我的),因为它所做的只是让^$分别匹配行的开头和结尾。但是没有一个模式包含这些元字符。所以修饰语没有做任何事情。

我的控制台输出:

PS> $x = "<span>[Mobile: %mobile% |] Phone: %telephone% [| Fax: &nbsp;&nbsp;%faxNumber%]</span>"
PS> $x -ireplace '\[([^\]:]*)Mobile([^\]]*)\]', 'MyReplacement1'
<span>MyReplacement1 Phone: %telephone% [| Fax: &nbsp;&nbsp;%faxNumber%]</span>
PS> $x -ireplace '\[([^\]:]*)Fax([^\]]*)\]', 'MyReplacement2'
<span>[Mobile: %mobile% |] Phone: %telephone% MyReplacement2</span>