Regex 正则表达式:在字符串末尾匹配复数大小写

Regex 正则表达式:在字符串末尾匹配复数大小写,regex,Regex,处理Java正则表达式,该正则表达式将匹配字符串末尾的“es”或“s”,并返回不带该后缀的子字符串。看起来很简单,但我无法让“e”与我正在尝试的表达式匹配 以下是我应该得到的输出: “英寸”->“英寸” “米”->“米” “盎司”->“盎司” 但是对于这个正则表达式: Pattern.compile("(.+)(es|s)$", Pattern.CASE_INSENSITIVE); 我实际上得到了: “英寸”->“英寸” 经过一些研究,我发现我搜索的“+”部分过于贪婪,并将其改为: Patte

处理Java正则表达式,该正则表达式将匹配字符串末尾的“es”或“s”,并返回不带该后缀的子字符串。看起来很简单,但我无法让“e”与我正在尝试的表达式匹配

以下是我应该得到的输出:

“英寸”->“英寸”

“米”->“米”

“盎司”->“盎司”

但是对于这个正则表达式:

Pattern.compile("(.+)(es|s)$", Pattern.CASE_INSENSITIVE);
我实际上得到了:

“英寸”->“英寸”

经过一些研究,我发现我搜索的“+”部分过于贪婪,并将其改为:

Pattern.compile("(.+?)(es|s)$", Pattern.CASE_INSENSITIVE);

解决了这个问题。然而,我的问题是,为什么“s”与“s”匹配?如果算法的“贪婪”性质是问题所在,那么它不应该匹配整个字符串吗?

简短回答

贪婪并不意味着贪婪。贪婪的目的是尽可能多地消费/吃;但会从字符串不再匹配的那一刻起停止

长答案

在正则表达式中,Kleene星(
*
)是贪婪的,这意味着它试图获取尽可能多的信息,但不能获取更多。考虑正则表达式:

(.+)(es|s)$
这里的
+
旨在尽可能多地吃。但只有在设法通过
(es | s)
时,才能到达正则表达式的末尾,这只有在它以至少一个
s
结尾时才可能。或者如果我们将您的字符串对齐
英寸

(.+)  (es|e)$
inche s
(增加空格)。换句话说,
+

当你让它不贪婪时,
+?
会尝试尽快放弃进食。对于字符串
英寸
,这在
英寸
之后:

(.+?) (es|e)$
inch  es

它不能早一点放弃,因为那样的话,
h
应该以某种方式与
(es | e)
相匹配

贪婪并不意味着贪婪。贪婪的目的是尽可能多地消费/吃;但会从字符串不再匹配的那一刻起停止

长答案

在正则表达式中,Kleene星(
*
)是贪婪的,这意味着它试图获取尽可能多的信息,但不能获取更多。考虑正则表达式:

(.+)(es|s)$
这里的
+
旨在尽可能多地吃。但只有在设法通过
(es | s)
时,才能到达正则表达式的末尾,这只有在它以至少一个
s
结尾时才可能。或者如果我们将您的字符串对齐
英寸

(.+)  (es|e)$
inche s
(增加空格)。换句话说,
+

当你让它不贪婪时,
+?
会尝试尽快放弃进食。对于字符串
英寸
,这在
英寸
之后:

(.+?) (es|e)$
inch  es

它不能过早放弃,因为
h
应该以某种方式与
(es | e)
匹配。当它贪婪地匹配时,它会在满足表达式的同时尽可能多地匹配。所以当它贪婪的时候,它会拿走除了s以外的所有东西,因为它不能拿走s并且仍然满足表达式。当它非贪婪地匹配时,它会在满足表达式的同时尽可能少地匹配。因此,它将接受除“es”之外的所有内容,因为这是在满足表达式时所能接受的最小值。

当它贪婪地匹配时,它会在满足表达式时尽可能多地匹配。所以当它贪婪的时候,它会拿走除了s以外的所有东西,因为它不能拿走s并且仍然满足表达式。当它非贪婪地匹配时,它会在满足表达式的同时尽可能少地匹配。因此,它将接受除“es”之外的所有内容,因为在满足表达式的情况下,这是尽可能少的。

它可以逐行执行,而不是多行执行。你是只得到了一个结果,还是也得到了“米”和“盎司”的结果?你似乎在试图解析英语,我认为这不是一种常规语言。我想你需要看看自然语言处理,除非你处理的是一个非常小的单词子集。看看。它可以一行一行地处理,而不是多行。你是只得到了一个结果,还是也得到了“米”和“盎司”的结果?你似乎在试图解析英语,我认为这不是一种常规语言。我想你需要看看自然语言处理,除非你处理的是一小部分单词。