例如,我有一个字符串:
/div1/div2[/div3[/div4]]/div5/div6[/div7]
现在,我想将内容拆分为“/
”,并忽略“[ ]
”中的内容。
结果应为:
div1
div2[/div3[/div4]]
div5
div6[/div7]
如何使用正则表达式获得结果?我的编程语言是JavaScript。
答案 0 :(得分:3)
您无法使用正则表达式执行此操作,因为它是递归的。 (这回答了你的问题,现在看看我是否可以优雅地解决问题......)
编辑:aem让我失望! :d只要每个[
后跟/
,就可以正常工作。它不验证字符串的格式是否正确。
string temp = text.Replace("[/", "[");
string[] elements = temp.Split('/').Select(element => element.Replace("[", "[/")).ToArray();
答案 1 :(得分:2)
您可以先将双字符序列[/转换为您知道不会出现在输入中的另一个字符或序列,然后将字符串拆分为/ boundary,然后将翻译后的序列重新转换回[/ in结果字符串。这甚至不需要正则表达式。 :)
例如,如果您知道[在输入序列中不会单独显示,则可以在初始步骤中替换[/] [
答案 2 :(得分:2)
这有效......
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main(string[] args)
{
string testCase = "/div1/div2[/div3[/div4]]/div5/div6[/div7]";
//string pattern = "(?<Match>/div\\d(?:\\[(?>\\[(?<null>)|\\](?<-null>)|.?)*(?(null)(?!))\\])?)";
string pattern = "(?<Match>div\\d(?:\\[(?>\\[(?<null>)|\\](?<-null>)|.?)*(?(null)(?!))\\])?)";
Regex rx = new Regex(pattern);
MatchCollection matches = rx.Matches(testCase);
foreach (Match match in matches)
Console.WriteLine(match.Value);
Console.ReadLine();
}
}
礼貌...... http://retkomma.wordpress.com/2007/10/30/nested-regular-expressions-explained/
答案 3 :(得分:1)
根据您的发布历史判断,我猜您正在谈论C#(.NET)正则表达式。在这种情况下,这应该工作:
Regex.Split(target, @"(?<!\[)/");
这假设每个非分隔符/
前面都有一个左方括号,就像样本数据一样。
您应该始终指定您正在使用的正则表达式。例如,这种技术需要支持外观的风味。在我的脑海中,包括Perl,PHP,Python和Java,但不包括JavaScript。
编辑:这是Java中的演示:
public class Test
{
public static void main(String[] args)
{
String str = "/div1/div2[/div3[/div4]]/div5/div6[/div7]";
String[] parts = str.split("(?<!\\[)/");
for (String s : parts)
{
System.out.println(s);
}
}
}
输出:
div1
div2[/div3[/div4]]
div5
div6[/div7]
当然,我在这里依赖于一些简化的假设。如果我的任何假设都错了,我相信你会告诉我,迈克。 :)
编辑:仍在等待迈克关于这些假设的裁决,但Chris Lutz在他对280Z28的评论中提出了一个很好的观点。在示例字符串的根级别,有两个地方可以看到两个连续的/divN
标记,但在每个其他级别,标记始终通过方括号彼此隔离。我的解决方案,如280Z28,假设总是如此,但如果数据看起来像这样呢?
/div1/div2[/div3/div8[/div4]/div9]/div5/div6[/div7]
现在我们有两个地方,非分隔符斜线不前面有一个左方括号,但基本的想法是。从任何一点开始,如果你向前扫描寻找方括号,你找到的第一个将始终是一个左(或开口)括号。如果向后扫描,您将始终首先找到正确(或关闭)括号。如果这两个条件都不正确,那么您就不在根级别。将其转化为外观,你得到了这个:
/(?![^\[\]]*\])(?<!\[[^\[\]]*)
我知道它变得非常粗糙,但是我会在一周的任何一天接管那些神圣的递归。 ;)另一个好处是你不必知道任何关于令牌的事情,除了它们以斜杠开头并且不包含任何方括号。顺便说一下,这个正则表达式包含一个可以匹配任意数量字符的lookbehind;支持的正则表达式列表确实很短,但.NET可以做到。
答案 4 :(得分:0)
在不知道您所针对的正则表达式引擎的情况下,我只能猜测哪些适用于您。如果您使用的是.Net,请查看此处:http://blogs.msdn.com/bclteam/archive/2005/03/15/396452.aspx
如果您使用的是perl,请查看此处:http://metacpan.org/pod/Regexp::Common::balanced
答案 5 :(得分:0)
实验示例,使用PHP和拆分方法,但仅在样本字符串上进行测试。
$str = "/div1/div2[/div3[/div4]]/div5/div6[/div7]/div8";
// split on "/"
$s = explode("/",$str);
foreach ($s as $k=>$v){
// if no [ or ] in the item
if( strpos($v,"[")===FALSE && strpos($v,"]") ===FALSE){
print "\n";
print $v."\n";
}else{
print $v . "/";
}
}
输出:
div1
div2[/div3[/div4]]/
div5
div6[/div7]/
div8
注意:最后有“/”,所以只需要一点修剪就可以得到理想的结果。
答案 6 :(得分:0)
s/\/(div\d{0,}(?:\[.*?\])?)/$1\n/