Regex 要在第一次匹配时停止的正则表达式

Regex 要在第一次匹配时停止的正则表达式,regex,Regex,我的正则表达式模式看起来像 <xxxx location="file path/level1/level2" xxxx some="xxx"> 似乎不起作用。您需要使正则表达式不贪婪,因为默认情况下,“(.*)”将匹配所有“文件路径/level1/level2”xxx some=“xxx” 相反,您可以使您的点星不贪婪,这将使其匹配尽可能少的字符: /location="(.*?)"/ 在量词(?、*或+)上添加?)可以使其不贪婪。如果引擎支持,请使用非贪婪匹配。添加?在捕获过程

我的正则表达式模式看起来像

<xxxx location="file path/level1/level2" xxxx some="xxx">

似乎不起作用。

您需要使正则表达式不贪婪,因为默认情况下,
“(.*)”
将匹配所有
“文件路径/level1/level2”xxx some=“xxx”

相反,您可以使您的点星不贪婪,这将使其匹配尽可能少的字符:

/location="(.*?)"/

在量词(
*
+
)上添加
)可以使其不贪婪。

如果引擎支持,请使用非贪婪匹配。添加?在捕获过程中

/location="(.*?)"/
location=“(.*)”
将从“after
location=
匹配到“after
some=“xxx
”,除非您将其设置为非贪婪。因此,您要么需要
*?
(即,使其非贪婪),要么最好将
*
替换为
[^]*

如何

.*location="([^"]*)".*

这避免了使用.*进行无限制搜索,并将与第一个引号完全匹配。

使用无全局标志的惰性量词

例如

如果您有全局标志
/g
,那么它将匹配所有最低长度的匹配项,如下所示。

因为您使用的是量化子模式,如中所述

默认情况下,量化的子模式是“贪婪的”,也就是说,它将 尽可能多次匹配(给定特定起始位置) 同时仍然允许模式的其余部分匹配。如果你想要的话 要匹配可能的最小次数,请跟随量词 带有“?”符号。请注意,含义不会改变,只是 “贪婪”:

因此,为了使您的量化模式进行最小匹配,请遵循

/location="(.*?)"/
还有一种方法

这是你想要的。这是懒惰的
[\s\s]*?

第一项:
[\s\s]*?(?:location=“[^”]*”[\s\s]*
替换为:
$1

解释


为完整起见,这将得到最后一个。这是贪婪的
[\s\s]*

最后一项:
[\s\s]*(?:location=“([^”]*)”[\s\s]*
替换为:
$1

解释



这两个正则表达式之间只有一个区别,那就是

这里的其他答案无法为不支持非贪婪匹配的正则表达式版本提供完整的解决方案。贪婪量词(
*?
+?
等)是传统正则表达式不支持的Perl 5扩展

如果您的停止条件是单个字符,则解决方案很简单;而不是

a(.*?)b
你可以匹配

a[^ab]*b
i、 e指定一个字符类,该字符类不包括起始和结束字符

在更一般的情况下,您可以精心构造一个表达式,如

start(|[^e]|e(|[^n]|n(|[^d])))end
捕获
开始
和第一次出现的
结束
之间的匹配。请注意,带有嵌套括号的子表达式如何列出了许多备选方案,它们之间仅允许
e
,前提是后面没有
nd
等等,并且还要注意将空字符串作为一个备选方案覆盖,该备选方案与在该特定点不允许的内容不匹配

当然,在大多数情况下,正确的方法是为您试图解析的格式使用适当的解析器,但有时,可能一个解析器不可用,或者您使用的专用工具坚持使用正则表达式而不是其他

import regex
text = 'ask her to call Mary back when she comes back'                           
p = r'(?i)(?s)call(.*?)back'
for match in regex.finditer(p, str(text)):
    print (match.group(1))
输出:
Mary

你的来源是什么,是HTML还是xml或其他什么?为什么这是一个社区维基?这是一个真正的问题。现在太晚了。你用什么语言写?请不要将正则表达式用于XML。如果您只想扫描简单属性,那么有很多更好的方法来解析XMLNot。正则表达式是合适的,而且速度更快。我想说,如果您使用代码c#作为示例,使用linq更好。我怀疑如果你有一个好的解析器,使用正则表达式会更好,如果你使用VIM,这个正则表达式需要有点不同:不是
*?
而是
\{-}
进行非贪婪匹配。谢谢Daniel。“在量词(?,*或+)上加一个?使其不贪婪。”这对我来说是个有用的提示?描述了我在试图弄明白这一点时的困惑。我相信你可以说‘lazy’而不是‘non-greedy’,因为dnesn问题没有指定特定的正则表达式方言,这个答案应该说明它只在实现Perl 5扩展(Java、Ruby、Python等)的正则表达式引擎中可用,而在“传统”正则表达式引擎中不可用(包括JavaScript、Awk、
sed
、不带
-P
grep
等)。[^“]*在大多数正则表达式引擎中也可能更快,因为它不需要在当前模式之后查找模式。@Kip:你可能是对的,但是
*?
符号比
[^]更通用*
如果我想使用[^”]*包含分隔符,如果您不知道这里的“^”和[]是什么意思,那就不必了。大多数人都会理解的。*由于上述原因,如果考虑到可移植性,应该首选这种模式。
start(|[^e]|e(|[^n]|n(|[^d])))end
import regex
text = 'ask her to call Mary back when she comes back'                           
p = r'(?i)(?s)call(.*?)back'
for match in regex.finditer(p, str(text)):
    print (match.group(1))