如果我有一个字符分隔的字符串,那么就这样说:
a-b-c
我希望保留分隔符,我可以使用look-behind和look-ahead来保留分隔符,例如:
string.split("((?<=-)|(?=-))");
导致
a
-
b
-
c
现在,如果其中一个分隔符被转义,就像这样:
a-b\-c
我想要逃避,我想要使用这样的正则表达式:
((?<=-(?!(?<=\\-))) | (?=-(?!(?<=\\-))))
麦角
string.split("((?<=-(?!(?<=\\\\-)))|(?=-(?!(?<=\\\\-))))"):
现在,这有效并导致:
a
-
b\-c
(我后来用string.replace("\\", "");
删除了反斜杠,我还没有找到将其包含在正则表达式中的方法)
我的问题是理解之一 按照我理解的方式,正则表达式就是
split ((if '-' is before (unless ('\-' is before))) or (if '-' is after (unless ('\-' is before))))
为什么最后一部分不应该是“除非\
之前”?如果' - '之后,那意味着我们介于'\'和' - '之间,所以只有\
应该在之前,而不是\\-
,但如果我更改正则表达式则不起作用像这样反映:
((?<=-(?!(?<=\\-))) | (?=-(?!(?<=\\))))
结果:a
,-
,b\
,-c
这是什么原因?我的推理错误在哪里?
答案 0 :(得分:1)
虽然这并没有真正回答这个问题,但这解释了外观如何运作。
Lookarounds是锚点:它们不使用文本,但在输入文本中找到位置。你的正则表达式可以用更简单的方式编写:
(?<=-)(?<!\\-)|(?=-)(?<!\\)
你在这里有四个外观:正面和负面的外观,正面和负面的前瞻。
完整的正则表达式是:
(?<=-) # Find a position where what precedes is a dash
(?<!\\-) # Find a position where what precedes is not \-
| # Or
(?=-) # Find a position where what follows is a dash
(?<!\\) # Find a position where what precedes is not a \
注意术语“位置”。请注意,锚根本不会在文本中前进。
现在,如果我们尝试将该正则表达式与a-b\-c
匹配:
# Step 1
# Input: | a-b\-c|
# Position: |^ |
# Regex: | (?<=-)(?<!\\-)|(?=-)(?<!\\)|
# Position: |^ |
# No match, try other alternative
# Input: | a-b\-c|
# Position: |^ |
# Regex: |(?<=-)(?<!\\-)| (?=-)(?<!\\)|
# Position: | ^ |
# No match, regex fails
# Advance one position in the input text and try again
# Step 2
# Input: |a -b\-c|
# Position: | ^ |
# Regex: | (?<=-)(?<!\\-)|(?=-)(?<!\\)|
# Position: |^ |
# No match, try other alternative
# Input: |a -b\-c|
# Position: | ^ |
# Regex: |(?<=-)(?<!\\-)| (?=-)(?<!\\)|
# Position: | ^ |
# Match: a "-" follows
# Input: |a -b\-c|
# Position: | ^ |
# Regex: |(?<=-)(?<!\\-)|(?=-) (?<!\\)|
# Position: | ^ |
# Match: what precedes is not a \
# Input: |a -b\-c|
# Position: | ^ |
# Regex: |(?<=-)(?<!\\-)|(?=-)(?<!\\) |
# Position: | ^|
# Regex is satisfied
这是一种不使用拆分而且没有外观的替代方案:
[a-z]+(\\-[a-z]+)*|-
您可以在Pattern
中使用此正则表达式并使用Matcher
:
public static void main(final String... args)
{
final Pattern pattern
= Pattern.compile("[a-z]+(\\\\-[a-z]+)*|-");
final Matcher m = pattern.matcher("a-b\\-c");
while (m.find())
System.out.println(m.group());
}
答案 1 :(得分:0)
为什么最后一部分不应该“除非\之前”?
在
(?=-(?!(?<=\\-))))
^here
光标位于-
之后,因此"unless \ is before"
始终为false,因为我们在当前位置之前始终有-
。
可能更容易正则表达式
(?<=(?<!\\\\)-)|(?=(?<!\\\\)-)
(?<=(?<!\\\\)-)
会检查我们之前是否-
之前没有\
。(?=(?<!\\\\)-)
会检查我们之前是否-
之前没有\
。