我正在尝试学习正则表达式并感到困惑。
我看到了这篇文章java split () method
所以我对Achintya Jha的第二个答案有一些疑问;
str2.split("");
为什么要[, 1, 2, 3]
""
,如果是,为什么它最后没有检测到相同的内容?(?!^)
到底是什么意思?如果我没有错,a(?!b)
如果a后面没有a
,则会返回b
并且^
找到必须在该行开头匹配的正则表达式,以便(?!^)
获得一个空字符串""
并且^
找到必须在该行开头匹配的""
如果此""
后面没有""
?
""
答案 0 :(得分:3)
拆分发生在匹配作为参数传递的正则表达式的地方。你需要知道,如果分裂发生,一件事就变成了两件事。总是。没有例外。
您可以怀疑它,因为实例"abc".split("c")
返回带有一个元素["ab"]
的数组,但这是因为此版本的split
在返回之前还会自动从数组中删除尾随的空字符串。
换句话说"abc".split("c")
["ab",""]
数组(是的,有空字符串,这是在"abc"
上拆分c
的结果),["ab"]
另一个例子是在"abc"
上拆分"a"
。由于a
在开始时出现,您将获得["", "bc"]
。
但是拆分空字符串有点棘手,因为空字符串在每个字符之前和之后。我将使用管道|
标记它们。
"abc"
这些位置"|a|b|c|"
中可以找到空"abc"
中的空字符串,这意味着当您""
上["", "a", "b", "c", ""]
分开时,<{1}}
"abc".split("")
这就是["", "a", "b", "c"]
作为结果数组"|a|b|c|"
返回的原因(这应该回答你的问题1)。
但是如果我们想要防止第一个空字符串(开头的那个)被split方法匹配怎么办?换句话说,如果我们不想拆分
,该怎么办? "a|b|c|"
但仅限于
a|
我们可以通过几种方式实现这一目标。
b|
c|
""
。 要创建此类正则表达式,我们需要look-around个机制。
(?<=.)
"(?<=.)"
。 如果我们将以前的两个品脱结合起来:""
和"(?<=.)"+""
,我们会得"(?<=.)"
"abc".split("(?<=.)")
,因此.
只能在这些空以任何字符开头的字符串(以点(?<!...)
表示的正则表达式)。
要说某些内容不能停留在字符串的开头,我们可以使用负面观察^
和(?<!^)
来表示字符串的开头。所以"(?<!^)
表示条件&#34;在它之前没有字符串的开头&#34;。这就是为什么 ↓
"|a|b|c|"
无法匹配此空格
(?!^)
因为它之前有字符串的开头。
实际上还有一个特殊情况是你的问题的主要观点^
,这意味着负向前瞻。这个正则表达式描述了空字符串,后面没有字符串的开头。它有点不直观,因为之前我们假设字符串的开头(由 ↓
"^|a|b|c|"
表示)放在这里
↓
"|^a|b|c|"
但现在它看起来像是在这里:
↓
"^abc"
那是怎么回事?它是如何工作的?
正如我之前所说,拆分空字符串很棘手。要理解这一点,你需要看看没有标记空字符串的字符串,你会看到字符串的开头就在这里
"a"
换句话说,正则表达式也考虑在第一个字符(在我们的例子中为 ↓
"|^a|b|c|"
)之前的位置作为其开头,所以
(?!^)
也有意义且有效,这就是 ↓
"|^a|b|c|"
能够看到这个空字符串
(?<=.)
在字符串开始之前,并且不接受它作为有效的分割位置。
无论如何,由于这对于不熟悉正则表达式的开发人员造成了混淆,因此从Java 8开始,我们不必使用(?<!^)
或(?!^)
或split
的技巧避免在开头创建空字符串,因为如本问题所述
Why in Java 8 split sometimes removes empty strings at start of result array?
它会在生成的数组的开头自动删除空字符串,因为"abc".split("")
中使用的长正则表达式代表zero-length字符串(如空字符串),因此您现在可以使用["a", "b", "c"]
和得到结果{{1}}。
答案 1 :(得分:2)
(1)
为什么str2.split("");
以[, 1, 2, 3]
(2)
的形式发出?它是否在文本开头检测到""
,如果是,为什么它不执行最后一样吗?`
通过拆分空字符串,它将返回空字符串作为第一项。如果您正在搜索的字符串中没有定义分隔符,您将获得一个大小为1
的数组,即使该字符串为空,它也会保留原始字符串。
(3)
(?!^)
究竟是什么意思?
这是一个Negative Lookahead断言,断言它不位于字符串开头之前/之后。
(?! # look ahead to see if there is not:
^ # the beginning of the string
) # end of look-ahead
你对Negative Lookahead的工作原理是正确的。
a(?!b) # matches a when not followed by b
答案 2 :(得分:1)
正则表达式:
(?!^)
输入开始是负面展望。这意味着&#34;没有在输入开始之前定位&#34;。
因为否则空白的正则表达式在开始之前匹配,这个断言会阻止它在那里分裂,所以它只在字符之间分开(不在开始和第一个字符之间)。
实现同样目标的另一个正则表达式是:
(?<=.)
对于任何角色来说都是一个背后的东西,即&#34;在任何角色之后#34;我觉得更清楚。