当字符串中的元素可以包含分隔符时,根据分隔符拆分字符串

时间:2010-03-17 20:16:54

标签: regex split

我有一个看起来像这样的字符串:

"#Text() #SomeMoreText() #TextThatContainsDelimiter(#blah) #SomethingElse()"

我想回来

[#Text(), #SomeMoreText(), #TextThatContainsDelimiter(#blah), #SomethingElse()]

我想到这样做的一种方法是要求将#转义为\#,这会产生输入字符串:

"#Text() #SomeMoreText() #TextThatContainsDelimiter(\#blah) #SomethingElse()"

然后我可以使用/[^\\]#/将其拆分,这样就可以了:

[#Text(), SomeMoreText, TextThatContainsDelimiter(\#blah), SomethingElse()]

第一个元素将包含#,但我可以删除它。但是,是否有更简洁的方法来执行此操作而不必转义#,并确保第一个元素不包含#?基本上我希望只有当#没有被括号括起来时,它才会被#拆分。

我的预感是,由于#是上下文相关的,并且正则表达式仅适用于无上下文的字符串,因此这可能不是正确的工具。如果是这样,我是否必须为此编写语法并滚动我自己的解析器/词法分析器?

2 个答案:

答案 0 :(得分:2)

哎呀!我倾向于失去我的能力。正则表达式(?<!\()(?=#)有效

PS Home:\> $s -split '(?<!\()(?=#)'

#Text()
#SomeMoreText()
#TextThatContainsDelimiter(#blah)
#SomethingElse()

这结合了一个负面的lookbehind (以确保在#之前没有一个左括号)和一个正向前瞻来寻找{ {1}}。

答案 1 :(得分:2)

从您的示例中,您看起来想要在紧跟着哈希符号的空格上拆分:

/\s+(?=#)/

在所有令牌上留下前导#,但您不需要特别处理第一个令牌。你也可以用这个:

/(?:^|\s+)#/

这将剥离哈希符号,代价是生成一个空字符串作为第一个标记。但是有些语言提供了一种丢弃空主要令牌的方法。请注意,JavaScript 支持前瞻,而不是后瞻。