我想拆分以下内容:
name[]address[I]dob[]nationality[]occupation[]
所以我的结果是:
name[]
address[I]
dob[]
nationality[]
occupation[]
我尝试使用Regex.Split
但无法获得这些结果。
我想拆分以下内容:
name[]address[I]dob[]nationality[]occupation[]
所以我的结果是:
name[]
address[I]
dob[]
nationality[]
occupation[]
我尝试使用Regex.Split
但无法获得这些结果。
您可以使用Regex.Split
以下正则表达式:
(?<=])(?=[a-z])
它将在左侧的右方括号和右侧的字母之间拆分。这是使用环视断言完成的。它们不消耗匹配的任何字符,因此在这个星座中它们非常方便地在字母之间进行匹配。
基本上它的意思正是我写的:(?<=])
将匹配字符串中前面有一个右括号的点,同时(?=[a-z])
匹配字符串中的一个点(都是零宽度,即字符之间),后面是一个字母。如果您的输入数据看起来与您在问题中给我们的数据不同,您可以稍微调整一下。
您还可以通过使用(?<=])\b
. 但我建议不要这样做,因为\b
通常情况下,\w
这是一件非常丑陋的事情。它的工作原理大致相同,但不完全一样,因为\b
在这种情况下,相当于(?=[\w])
并\w
匹配更多的东西,即十进制数字和下划线。
快速 PowerShell 测试(它使用相同的正则表达式实现,因为它是 .NET 下面):
PS> 'name[]address[I]dob[]nationality[]occupation[]' -split '(?<=])(?=[a-z])'
name[]
address[I]
dob[]
nationality[]
occupation[]
为了完整起见,还有另一种选择。您可以在要保留的标记之间拆分字符串,也可以只收集要保留的标记的所有匹配项。在后一种情况下,您需要一个与您需要的模式相匹配的模式,例如
[a-z]+\[[^\]]*]
或者丹尼斯给出的答案(我只是倾向于避免\w
,\b
除了快速和肮脏的黑客或打高尔夫球,因为我坚持认为它们没有有用的应用程序)。您可以将其与Regex.Matches
.
通常这两种方法都可以正常工作,然后取决于拆分或匹配模式是否更容易理解。因为Regex.Matches
你会得到Match
对象string[]
,所以如果你需要它,你实际上不会得到 a ,所以这也需要.Select(m => m.Value)
。
在这种情况下,我想这两个正则表达式都不应该单独留下来解释它的作用。我可以很好地阅读它们,但是许多开发人员对正则表达式有些不安,尤其是像环视这样的更高级的概念通常需要解释。
text.Split(new Char[] { ']' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s + "]").ToArray();
使用这个正则表达式模式:
\w*\[\w*\]
string inputString = "name[]address[I]dob[]nationality[]occupation[]";
var result = Regex.Matches(inputString, @".*?\[I?\]").Cast<Match>().Select(m => m.Groups[0].Value).ToArray();
正则表达式应该没问题。您还可以考虑使用 string.IndexOf 捕获开始和结束方括号,例如:
IEnumerable<string> Results(string input)
{
int currentIndex = -1;
while (true)
{
currentIndex++;
int openingBracketIndex = input.IndexOf("[", currentIndex);
int closingBracketIndex = input.IndexOf("]", currentIndex);
if (openingBracketIndex == -1 || closingBracketIndex == -1)
yield break;
yield return input.Substring(currentIndex, closingBracketIndex - currentIndex + 1);
currentIndex = closingBracketIndex;
}
}