我试图仅在正则表达式的捕获组上拆分字符串,但我似乎在整个匹配中分裂。
我想在hi|my~~|~|name is bob
之前将|
分开,前面有零或任意偶数~
的
所以我的预期输出是Array(hi, my~~, ~|name is bob)
我正在使用正则表达式"(?<!~)(?:~~)*(\\|)"
但"hi|my~~|~|name is bob".split("(?<!~)(?:~~)*(\\|)")
正在返回Array[String] = Array(hi, my, ~|name is bob)
,因为它会在~~|
之后的整个my
上分开,而不仅仅是|
之前的~~
}}
例如比较:
scala> "(?<!~)(?:~~)*(\\|)".r.findAllIn("hi|my~~|~|name is bob").foreach(println)
|
~~|
到
scala> "(?<!~)(?:~~)*(\\|)".r.findAllIn("hi|my~~|~|name is bob").matchData foreach { m => println(m.group(1)) }
|
|
修改:
一些背景和澄清:
我正在尝试将字符串列表序列化为由|
分隔的单个字符串。我无法保证|
(或任何与此有关的字符)不会出现在单个字符串中。
为了实现所需的功能,我想要转义所有出现的|
。我选择了~
作为我的逃脱角色。在我逃脱|
之前,我需要逃避~
。
一旦我转义了所有内容,我就可以使用|
加入列表,以获得代表我原始字符串列表的单个字符串。
然后稍后将单个字符串解析回原始列表,我只需要在未转义的|
上进行拆分。我必须要小心,因为像~~|
这样的东西实际上是一个未转义的管道,即使它包含~|
。这是因为转义字符本身是转义的,这意味着它只是我原始字符串中的“tilda”而不是用作“转义”。换句话说,我有一个以~
结尾的字符串,现在它已转义为~~
并通过“|”与列表中的下一个字符串连接。
好的,如果我的初始字符串列表为["hi","my~","|name is bob"]
,我将首先转义所有~
以获取["hi","my~~","|name is bob"]
。现在我将转义所有|
以获取["hi","my~~","~|name is bob"]
,最后我将加入|
以获取单个字符串:
“hi|my~~|~|name is bob"
现在,如果我要反转这一点,我需要首先拆分未转义的|
,这是|
前面有零或偶数~
的{{1}}。所以,如果我能用我的正则表达式实现这一点(到目前为止我在捕获组中正确捕获了这个,但我只是不知道如何仅应用组而不是完整的~~|
匹配例如分割),然后我会得到["hi","my~~","~|name is bob"]
。现在我只是忘记了我的~
,忘了我的|
,我已经回到原来的输入:
["hi","my~","|name is bob"]
答案 0 :(得分:3)
您需要所有~
成为后备组的一部分,因为split
会分割正则表达式的整个匹配,而不仅仅是一组它,即使该组是非捕获组。一个更简单的例子:
"asdf" split "(?:s)" //Array(a, df)
后视组不是比赛的一部分,所以你想把你的前缀标准放在那里。基本上,您需要将解决方案包装在另一个后视组中。理想情况下,您需要:
"""(?<=(?<!~)(~~)*)\|"""
但遗憾的是,Java并不支持任意长度的后视组。作为解决方法,您可以:
"""(?<=(?<!~)(~~){0,10})\|"""
只要有20个或更少,这对偶数个~
都有效。如果这是一个问题,你可以增加10。
如果嵌套的后视混乱,您也可以使用等效的:
"""(?<![^~]~(~~){0,10})\|"""