使用多字符正则表达式模式进行拆分,并保留定界符

时间:2018-09-18 10:11:58

标签: regex kotlin

我有下一个字符串和正则表达式用于拆分它:

val str = "this is #[loc] sparta"
val regex = "((?<=( #\\[\\w{3,100}\\] ))|(?=( #\\[\\w{3,100}\\] )))"
print(str.split(Regex(regex)))

//print - [this is,  #[loc] , sparta]

工作正常。但是在开发中,我没有意识到何时在[[***]块中不仅必须是文本(\ w)-他具有“-”和数字(UUID),而我的正确块是-

val str = "this is #[loc_75acca83-a39b-4df1-8c3c-b690df00db62]"

,在这种情况下,正则表达式不起作用。

如何针对新要求更改此部分-“ \ w {3,100}”?

我尝试更改为任何-“ \。{3,100}”-不起作用

1 个答案:

答案 0 :(得分:2)

要解决您的问题,您可以将regex替换为

val regex = """((?<=( #\[[^\]\[]{3,100}] ))|(?=( #\[[^\]\[]{3,100}] )))"""

\w可以替换为[^\]\[],除了[]以外的任何字符。

请注意,使用原始字符串文字"""..."""可以将单个反斜杠用作正则表达式转义。

请参见Kotlin online demo

或者,您可以使用以下方法分割并保留定界符:

private fun splitKeepDelims(s: String, rx: Regex, keep_empty: Boolean = true) : MutableList<String> {
    var res = mutableListOf<String>() // Declare the mutable list var
    var start = 0                     // Define var for substring start pos
    rx.findAll(s).forEach {           // Looking for matches     
        val substr_before = s.substring(start, it.range.first()) // // Substring before match start
        if (substr_before.length > 0 || keep_empty) {
            res.add(substr_before)      // Adding substring before match start
        }
        res.add(it.value)               // Adding match          
        start = it.range.last()+1       // Updating start pos of next substring before match
    }
    if ( start != s.length ) res.add(s.substring(start))  // Adding text after last match if any
    return res
}

然后,像使用它一样

val str = "this is #[loc_75acca83-a39b-4df1-8c3c-b690df00db62] sparta"
val regex = """#\[[\]\[]+]""".toRegex()
print(splitKeepDelims(str, regex))
// => [this is , #[loc_75acca83-a39b-4df1-8c3c-b690df00db62],  sparta]

请参见Kotlin demo

\[[^\]\[]+]模式匹配

  • \[-一个[字符
  • [^\]\[]+-除[]以外的1个以上的字符
  • ]-一个]字符。