正则表达式获取模式的最后一个匹配项
Regex to get the last match of a pattern
这是一个类似于我要匹配的字符串(为简单起见,除了几个特定模式外)。
Hello, tonight I'm in the town of Trenton in New Jersey and I will be staying in Hotel HomeStay [123] and I have no money.
我试图只匹配最后一个 in Hotel HomeStay [123]
。
我现在对前瞻和后视等正则表达式概念不是很熟悉。这里的类似问题似乎无法解决我的问题。我已经尝试了一堆正则表达式(据我所知),这就是我想出的 (?= (?:in|\d+))([\w \[]*\s*\d*\]*)(?!.*in)
。数字和特殊字符可能是我实际尝试匹配的部分内容。
前瞻和后视模式不限于仅包含 in
。他们也可以有更常用的词,例如 and
和 is
。我只是在寻找其中任何一个的最后一次出现,然后是非常独特的主要模式 - edit 假设匹配项必须包含 HomeStay
或 LuxuryInn
,为了示例。
然而,这匹配整个in the town of Trenton in New Jersey and I will be staying in Hotel HomeStay [123]
。
我哪里错了?另外,有人可以解释为什么 in
尽管被放置在非捕获组中但仍被捕获吗?
非常感谢任何帮助。
在java中:
String s = "Hello, tonight I'm in the town of Trenton in New Jersey and I will be "
+ "staying in Hotel HomeStay [123] and I have no money.";
// Garbage: final String SUBP = "\bin\s+(\S+)";
Pattern p = Pattern.compile("^.*\sin\s+(\S+).*$", Pattern.DOTALL);
String last = p.matcher(s).replaceFirst(""); // If found
这将查找 last“...在...”,因为 .*
(而不是热切的 .*?
)将查找最长的序列。
上面的结果将是 Hotel
(in
之后没有空格)但它可以是任何东西。
- Dot-All 会影响
.
也匹配换行符。
- 模式将从开头
^
到结尾 $
。
- 任意字符
.*
(最长)后跟空白字符 \s
。
- 然后是“in”,然后是组 1 中的一个词 (non-spaces
\S+
) (...)
- 然后是任何字符直到结束
.*
。对于纯度,最短序列应该是 .*?
。
- 结束
$
.
如果要检索包含 HomeStay
并以某些词为前缀但不包含这些词的文本,可以使用内部使用否定 look-ahead 的捕获组。下面的正则表达式捕获了所有事件 (working fiddle).
\b(?:in|and|is)\s+((?:.(?!\b(?:in|and|is)\b))*HomeStay(?:.(?!\b(?:in|and|is)\b))*)
在这里,正则表达式查找:
- 一个给定的前缀(
in
、and
或 is
作为一个 整个 单词,被分词符包围 \b
)
- ...后跟至少一个空白字符,
- ... 然后是 0 个或多个字符的序列 每个字符后面都没有前缀,
- ...接着是
HomeStay
,
- ... 后跟另一个 0 个或多个字符序列,每个字符后仍未跟前缀
如果你只想要最后一次出现,你可以在 (fiddle).
之后添加另一个否定 look-ahead
\b(?:in|and|is)\s+((?:.(?!\b(?:in|and|is)\b))*HomeStay(?:.(?!\b(?:in|and|is)\b))*)(?!.*HomeStay.*)
与上面相同,只是匹配的文本后面不能跟包含 HomeStay
.
的文本
最后,如果匹配文本必须至少包含列表中的一个词,只需将 HomeStay
的两次出现都替换为备选列表。寄宿家庭和豪华住宅示例:(?:HomeStay|Luxury)
(fiddle).
这是一个类似于我要匹配的字符串(为简单起见,除了几个特定模式外)。
Hello, tonight I'm in the town of Trenton in New Jersey and I will be staying in Hotel HomeStay [123] and I have no money.
我试图只匹配最后一个 in Hotel HomeStay [123]
。
我现在对前瞻和后视等正则表达式概念不是很熟悉。这里的类似问题似乎无法解决我的问题。我已经尝试了一堆正则表达式(据我所知),这就是我想出的 (?= (?:in|\d+))([\w \[]*\s*\d*\]*)(?!.*in)
。数字和特殊字符可能是我实际尝试匹配的部分内容。
前瞻和后视模式不限于仅包含 in
。他们也可以有更常用的词,例如 and
和 is
。我只是在寻找其中任何一个的最后一次出现,然后是非常独特的主要模式 - edit 假设匹配项必须包含 HomeStay
或 LuxuryInn
,为了示例。
然而,这匹配整个in the town of Trenton in New Jersey and I will be staying in Hotel HomeStay [123]
。
我哪里错了?另外,有人可以解释为什么 in
尽管被放置在非捕获组中但仍被捕获吗?
非常感谢任何帮助。
在java中:
String s = "Hello, tonight I'm in the town of Trenton in New Jersey and I will be "
+ "staying in Hotel HomeStay [123] and I have no money.";
// Garbage: final String SUBP = "\bin\s+(\S+)";
Pattern p = Pattern.compile("^.*\sin\s+(\S+).*$", Pattern.DOTALL);
String last = p.matcher(s).replaceFirst(""); // If found
这将查找 last“...在...”,因为 .*
(而不是热切的 .*?
)将查找最长的序列。
上面的结果将是 Hotel
(in
之后没有空格)但它可以是任何东西。
- Dot-All 会影响
.
也匹配换行符。 - 模式将从开头
^
到结尾$
。 - 任意字符
.*
(最长)后跟空白字符\s
。 - 然后是“in”,然后是组 1 中的一个词 (non-spaces
\S+
)(...)
- 然后是任何字符直到结束
.*
。对于纯度,最短序列应该是.*?
。 - 结束
$
.
如果要检索包含 HomeStay
并以某些词为前缀但不包含这些词的文本,可以使用内部使用否定 look-ahead 的捕获组。下面的正则表达式捕获了所有事件 (working fiddle).
\b(?:in|and|is)\s+((?:.(?!\b(?:in|and|is)\b))*HomeStay(?:.(?!\b(?:in|and|is)\b))*)
在这里,正则表达式查找:
- 一个给定的前缀(
in
、and
或is
作为一个 整个 单词,被分词符包围\b
) - ...后跟至少一个空白字符,
- ... 然后是 0 个或多个字符的序列 每个字符后面都没有前缀,
- ...接着是
HomeStay
, - ... 后跟另一个 0 个或多个字符序列,每个字符后仍未跟前缀
如果你只想要最后一次出现,你可以在 (fiddle).
之后添加另一个否定 look-ahead\b(?:in|and|is)\s+((?:.(?!\b(?:in|and|is)\b))*HomeStay(?:.(?!\b(?:in|and|is)\b))*)(?!.*HomeStay.*)
与上面相同,只是匹配的文本后面不能跟包含 HomeStay
.
最后,如果匹配文本必须至少包含列表中的一个词,只需将 HomeStay
的两次出现都替换为备选列表。寄宿家庭和豪华住宅示例:(?:HomeStay|Luxury)
(fiddle).