Html DotAll和多行正则表达式

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

我在Powershell中使用Rexex有点麻烦。好像有一个安装错误或什么的

我想要处理的文本是一个html文件,如下所示(示例1):

还有这个

$x = $x -ireplace '(?ms)\[(.?){7}Mobile(.*?)\]', 'MyReplacement2'
基本上,[标记变量的开始,]标记变量的结束。由此产生两个问题:

  • 因为我们有两个变量,mobile和fax,所以我使用
    (.?){7}
    来允许一些字符(这里是7个),并避免在第一个[nearmobile和最后一个]nearfax之间匹配孔部分(如果我使用
    (.*)
    而不是
    (.?){7}
    )。我不确定是否有其他选择,以便我可以在起始[和变量关键字“Fax”之间允许任何数量的字符(而不是7个字符)。这将有助于避免在添加
    之类的内容时出现错误匹配(其中仅7个字符是不够的,就像我说的
    (.*)
    将失败).希望我能解释清楚(有点难)-如果不能:请尽管问
  • Powershells-replace方法不提供设置正则表达式选项的方法,因此我使用(?ms)设置DotAll和多行模式。如您所见,我在我的正则表达式模式中使用它。但是:当添加新行时,如您在示例2中所见,在单词Mobile:%Mobile%之间,正则表达式失败,没有任何内容被替换
  • 我非常感谢专业人士的任何帮助,甚至是regex的建议,以避免我现在没有想到的任何进一步的问题

    编辑: (例3):

    [移动:
    %手机%|]电话:%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: &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>
    
    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: &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>