Java 正则表达式 - 捕获带有单个美元的字符串,但当它有两个连续的美元时则不捕获
Java Regex - capture string with single dollar, but not when it has two successive ones
我之前发布了 问题。
但这还没有结束。
那里适用的所有规则仍然适用。
所以字符串:
"%ABC%"
结果会产生 ABC(捕获百分号之间的内容)
- 和
"$ABC."
一样(捕获 $ 之后的东西,当出现另一个美元或点时放弃)
"$ABC$XYZ"
也会,结果也给XYZ
再补充一点:
"${ABC}"
也应该产生 ABC。 (如果存在则忽略花括号 - 可能是非捕获字符?)。
- 如果您有两个连续的美元符号,例如
"$$EFG"
,或 "$${EFG}"
,
应该不出现在正则表达式结果中。 (这是编号或命名反向引用发挥作用的地方——也是我将它们视为非捕获组的原因)。据我了解,一个组成为具有此语法 (?:)
的非捕获组。
1) 我可以说 % 或 $ 是非捕获组并按编号引用吗?还是只有捕获组才能分配编号?
2) 如果有((A) (B) (C))
,编号的顺序是什么?外组是1,A 2,B 3 C 4?
我一直在关注命名组。看到提到的语法 here
(?<name>capturing text)
to define a named group "name"
\k<name>
to backreference a named group "name"
3) 不确定是否可以在 Java 中命名非捕获组?有人可以解释一下吗?
- 更多信息here on non capture groups。
- 有关 lookbehinds
的更多信息
- 对问题 here 的类似回答,但没有得到我想要的答案。不确定 Java 中是否存在反向引用问题。
- 类似问题here。但是无法理解适用于此的工作版本。
我使用的 Java 与我原来的问题完全相同,除了:
String search = "/bla/$V_N.$$XYZ.bla";
String pattern = "(?:(?<oc>[%$]))(?!(\k<oc>))([^%.$]*)+";
这只会导致 V_N.
我真的很纠结这个问题,想知道是否有人可以帮助我解决这个问题。谢谢。
您可以使用多个捕获组编写更冗长的正则表达式,并且只抓取那些不是 null
的组,或者简单地连接找到的组值,因为在每个捕获组时总是只有一个被初始化比赛:
%([^%.]+)%|(?<!$)$(?:\{([^{}]+)\}|([^$.]+))
参见regex demo。
详情
%([^%.]+)%
- %
,第 1 组:除 %
和 .
之外的一个或多个字符,然后消耗 %
|
- 或
(?<!$)
- 与字符串中不紧跟 $
的位置相匹配的负后视
$
- 一个 $
(?:
- 匹配以下任一的非捕获容器组的开始:
\{([^{}]+)\}
- {
, 第 2 组:除 {
和 }
之外的任意一个或多个字符,则消耗 }
|
- 或
([^$.]+)
- 第 3 组:$
和 .
以外的 1 个或多个字符
)
- 非捕获容器组结束。
String regex = "%([^%.]+)%|(?<!\$)\$(?:\{([^\{}]+)\}|([^$.\s]+))";
String string = "%ABC%\n$ABC.\n$ABC$XYZ ${ABC}\n\n$$EFG $${EFG}.";
Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
Matcher m = pattern.matcher(string);
List<String> results = new ArrayList<>();
while (m.find()) {
results.add(Objects.toString(m.group(1),"") +
Objects.toString(m.group(2),"") +
Objects.toString(m.group(3),""));
}
System.out.println(results); // => [ABC, ABC, ABC, XYZ, ABC]
请注意,在常规 Java 字符串文字中,\
应该被转义(即 \
)以引入单个 文字 反斜杠用作 regex escapes.
的一部分
我之前发布了
但这还没有结束。 那里适用的所有规则仍然适用。
所以字符串:
"%ABC%"
结果会产生 ABC(捕获百分号之间的内容)- 和
"$ABC."
一样(捕获 $ 之后的东西,当出现另一个美元或点时放弃) "$ABC$XYZ"
也会,结果也给XYZ
再补充一点:
"${ABC}"
也应该产生 ABC。 (如果存在则忽略花括号 - 可能是非捕获字符?)。- 如果您有两个连续的美元符号,例如
"$$EFG"
,或"$${EFG}"
,
应该不出现在正则表达式结果中。 (这是编号或命名反向引用发挥作用的地方——也是我将它们视为非捕获组的原因)。据我了解,一个组成为具有此语法(?:)
的非捕获组。
1) 我可以说 % 或 $ 是非捕获组并按编号引用吗?还是只有捕获组才能分配编号?
2) 如果有((A) (B) (C))
,编号的顺序是什么?外组是1,A 2,B 3 C 4?
我一直在关注命名组。看到提到的语法 here
(?<name>capturing text)
to define a named group "name"
\k<name>
to backreference a named group "name"
3) 不确定是否可以在 Java 中命名非捕获组?有人可以解释一下吗?
- 更多信息here on non capture groups。
- 有关 lookbehinds 的更多信息
- 对问题 here 的类似回答,但没有得到我想要的答案。不确定 Java 中是否存在反向引用问题。
- 类似问题here。但是无法理解适用于此的工作版本。
我使用的 Java 与我原来的问题完全相同,除了:
String search = "/bla/$V_N.$$XYZ.bla";
String pattern = "(?:(?<oc>[%$]))(?!(\k<oc>))([^%.$]*)+";
这只会导致 V_N.
我真的很纠结这个问题,想知道是否有人可以帮助我解决这个问题。谢谢。
您可以使用多个捕获组编写更冗长的正则表达式,并且只抓取那些不是 null
的组,或者简单地连接找到的组值,因为在每个捕获组时总是只有一个被初始化比赛:
%([^%.]+)%|(?<!$)$(?:\{([^{}]+)\}|([^$.]+))
参见regex demo。
详情
%([^%.]+)%
-%
,第 1 组:除%
和.
之外的一个或多个字符,然后消耗%
|
- 或(?<!$)
- 与字符串中不紧跟$
的位置相匹配的负后视
$
- 一个$
(?:
- 匹配以下任一的非捕获容器组的开始:\{([^{}]+)\}
-{
, 第 2 组:除{
和}
之外的任意一个或多个字符,则消耗}
|
- 或([^$.]+)
- 第 3 组:$
和.
以外的 1 个或多个字符
)
- 非捕获容器组结束。
String regex = "%([^%.]+)%|(?<!\$)\$(?:\{([^\{}]+)\}|([^$.\s]+))";
String string = "%ABC%\n$ABC.\n$ABC$XYZ ${ABC}\n\n$$EFG $${EFG}.";
Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
Matcher m = pattern.matcher(string);
List<String> results = new ArrayList<>();
while (m.find()) {
results.add(Objects.toString(m.group(1),"") +
Objects.toString(m.group(2),"") +
Objects.toString(m.group(3),""));
}
System.out.println(results); // => [ABC, ABC, ABC, XYZ, ABC]
请注意,在常规 Java 字符串文字中,\
应该被转义(即 \
)以引入单个 文字 反斜杠用作 regex escapes.