【问题标题】:What does (?ms) in Regex mean?正则表达式中的 (?ms) 是什么意思?
【发布时间】:2015-02-25 02:55:03
【问题描述】:

我在 Powershell 中有以下正则表达式:

[regex]$regex = 
@'
(?ms).*?<DIV class=row>.*?
'@

这里的 (?ms) 是什么意思。

【问题讨论】:

  • 我知道它与多行/单行有关,但不太了解它是如何工作的
  • m 修饰符和s 修饰符是互斥的。您的正则表达式 (?ms).*?&lt;DIV class=row&gt;.*? 中没有任何内容受到 m 修饰符的影响。
  • FWIW,我相信我写了正则表达式,这是以下内容的片段:stackoverflow.com/questions/27649560/…。 @sln 提供的答案很好地解释了为什么使用它。
  • @Arora - 我来得太晚了,无法为答案添加太多内容,但是问题的框架方式,只有正则表达式的那个片段,它往往会产生关于它为什么存在的问题。希望线程链接能提供一些上下文和如何使用它的示例。

标签: regex powershell


【解决方案1】:

(?m) 是多行模式的修饰符。它使^$ 分别匹配一行的开头和结尾,而不是匹配输入的开头和结尾。

例如,给定输入:

ABC DEF
GHI

正则表达式 ^[A-Z]{3} 将匹配:

  1. "ABC"

同时,正则表达式 (?m)^[A-Z]{3} 将匹配:

  1. "ABC"
  2. "GHI"

(?s) 是单行模式的修饰符。它将换行符和换行符添加到. 将匹配的字符列表中。

给定与之前相同的输入,正则表达式 [A-Z]{3}. 将匹配(注意包含空格字符):

  1. "ABC "

虽然正则表达式 (?s)[A-Z]{3}. 将匹配:

  1. "ABC "
  2. "DEF\n"

尽管名称不同,但这两种模式并不一定是相互排斥的。在某些实现中,它们相互抵消,但在大多数情况下,它们可以协同使用。您可以通过编写(?m)(?s) 或简写为(?ms) 来同时使用两者。

编辑:

在某些情况下,您可能需要使用(?ms)。下面的例子有点做作,但我认为它们符合我们的目的。给定输入(注意“ABC”后面的空格):

ABC
DEF
GHI

正则表达式(?ms)^[A-Z]{3}. 匹配:

  1. "ABC "
  2. "DEF\n"

(?m)^[A-Z]{3}.(?s)^[A-Z]{3}. 匹配时:

  1. "ABC "

【讨论】:

  • 谢谢!你能解释一下我们什么时候可以使用 (?ms)
  • 这些模式何时互斥。它们完全不同且不相关。
  • @sln (?s)(?m) 不是“完全不同且不相关”。正如 Sam Holder 在他的回答中指出的那样,在 Tcl 中,(?s)(?m) 相互阻塞,但在其他实现中,它们不会。这是特定于实现的东西,您不能假设它们可以在所有正则表达式实现中一起使用。
  • 那么我相信 Ruby 和 Tcl 正在尝试实现短语单/多行模式的真正语言意义,而无需实际处理两者可以同时结合的丰富和强大的用途。它的不幸。全部点和多行模式是必不可少的工具,它们被设计为互斥并一起或单独使用。看起来他们是残废的引擎。希望他们有一天能修复它。
【解决方案2】:

有时人们说(?s) 是单行模式。它不是,没有这样的东西。
这意味着点元字符 . 匹配任何换行符,这意味着点匹配任何字符。
默认值通常是 Dot Not 匹配换行符,所以你必须特别
通过正则表达式选项常量或内联修饰符(?s) 设置点全修饰符。

(?m) 是多行修饰符。它让锚点^$ 匹配行的开头/结尾,如
以及字符串的开头/结尾。

(?ms) 如何/何时/应该一起使用?
答案是有时您想使用点来跨越换行符,同时
需要^ 在行首匹配。 而且你不确定介于两者之间的任何事情。

例子:

(?ms)^BlockStart.*?BlockEnd

输入在哪里:

StringStart aasdfasdffasdf
asgasgasgw fasfggasfgaag
BlockStart asgdfasggafsdgadsfg aaaasfgaafdsgasfg afbaadsf afdsgadsfg BlockEnd afsbgafsdgasfg
aaaaaafrgasfgaadsfgg

【讨论】:

  • 你有(?s) 不是单行模式的来源吗?根据man page for PCRE,它与现代正则表达式的标准一样接近,(?s) 是“单行(dotall)”模式。
  • @Tutleman - 早在正则表达式开始时,“单行模式”短语就被错误引用,与现代正则表达式无关。没有上下文意味着正则表达式中的单行。不过,多行是有上下文的,这意味着单行不是与多行相反。如果是这种情况,他们会互相抵消,(?ms) 毫无意义。我认为single-line_mode 是记录分隔符变量概念的口头保留,因为缺乏定义。然后dotall 短语开始被用来避免这样的问题。
【解决方案3】:

我想这些是mode modifiers

从链接的网站上说:

  • (?s) for "single line mode" 使点匹配所有字符,包括换行符。 Ruby 或 JavaScript 不支持。在 Tcl 中,(?s) 也使插入符号和美元仅在字符串的开头和结尾匹配。
  • (?m) for "multi-line mode" 使主题字符串中每一行的开头和结尾处的插入符号和美元匹配。在 Ruby 中,(?m) 使点匹配所有字符,而不会影响在 Ruby 中始终匹配每行开头和结尾的插入符号和美元。在 Tcl 中,(?m) 还可以防止点匹配换行符。

我不能 100% 确定您为什么要同时指定多行和单行模式,但页面上的示例也这样做了,所以它可能是有效的......

【讨论】:

猜你喜欢
  • 2011-06-15
  • 2012-06-10
  • 1970-01-01
  • 2012-09-07
  • 2011-08-28
  • 1970-01-01
  • 2020-01-11
  • 2021-04-05
相关资源
最近更新 更多