我想按/
分割字符串,但也允许'
和'
之间的任何内容包含我的分割字符。从分割中移除'
和'
以及任何空白。
示例/'TEST/:1'/3
分为
Test/:1
3
我有一些接近的东西:
regex.split(test, "/(?=(?:[^']*'[^']*')*[^']*$)"
但它仍然有'
和空白。
string[] fields = Regex.Split(Path, "/(?=(?:[^']*'[^']*')*[^']*$)");
对不起我很清楚它我自己的路径格式解析EDI就像文件一样工作。 /Location:LineNumber/YPosition
。我想要做的就是进入命令行/TEST:4/6 = /Location(Test):LineNumber(4)/YPosition(6)
。但我的问题是,我的代码确定了位置,可能是第一个分隔符。它可以是日期格式12/03/03
,它在EDI类型文件中很常见。
我希望能够让我的命令看起来像这样/'12/03/03':4/6
,这样当我的regex.split拆分位置时,它不会在('和')位置之间包含任何内容。
请帮忙吗?
答案 0 :(得分:1)
你真正想要实现的目标并不完全清楚。如果要解析类似CSV的文件格式,最好使用CSV解析器;如果要操作文件路径,则使用标准库的路径操作函数。与简单的正则表达式相比,两者都能更好地处理边缘情况。
那就是说,你可以做到
MatchCollection allMatchResults = null;
Regex regexObj = new Regex(
@" "" [^""]* "" # either match a (double-)quoted string
| # or
[^/\s]* # a sequence of characters other than / or whitespace",
RegexOptions.IgnorePatternWhitespace);
allMatchResults = regexObj.Matches(subjectString);
这不会处理带引号的字符串中的转义引号,但如果输入中没有引号,则它应该有效。
请注意,"Test / 1"/1/2 3/45
将分为"Test / 1"
,1
,2
,3
和45
,因为空白会被删除,因此作为分隔符。
答案 1 :(得分:1)
class Program
{
static void Main(string[] args)
{
string input = "\"\"/one/\"two/threefour\"/five//";
var separator = "/";
var empty = "(?<empty>\\s*)";
var word = string.Format("(?<word>[^{0}]+)", separator);
var quotedWord = "(?<word>[^\\\"]+)";
var token = string.Format("((\"({0}|{1})\")|({0}|{2}))",empty, quotedWord, word);
var pattern = string.Format("({0}/)+({0})", token);
foreach (var capture in Regex.Match(input, pattern).Groups["word"].Captures)
Console.WriteLine(capture);
}
}
答案 2 :(得分:1)
Split
并非真正适合此类工作的工具。如果你只是在斜杠上拆分它会很好,但是通过添加可选引号,匹配字段而不是分隔符变得更容易。这是一个允许单引号或双引号字符串的正则表达式,并将/
,:
和空格视为分隔符:
Regex r1 = new Regex(@"
""(?<FIELD>[^""]*)""
|
'(?<FIELD>[^']*)'
|
(?<FIELD>[^""'/:\s]+)
", RegexOptions.IgnorePatternWhitespace);
string[] source = { @"/TEST:4/6", @"/'12/03/03':4/6" };
foreach (string s in source)
{
foreach (Match m in r1.Matches(s))
{
Console.WriteLine(m.Groups["FIELD"].Value);
}
Console.WriteLine();
}
输出:
TEST
4
6
12/03/03
4
6
如果字段中包含引号,则重新使用FIELD
组名称可以轻松删除引号。这是一种更“语义”的方法,它在一次传递中匹配整个字符串,并使用命名组来对字段值进行归类。我只是将它们插入到替换字符串中,但您可以使用Groups
方法访问它们,就像我在第一个示例中所做的那样。
Regex r2 = new Regex(@"
/ \s*
(?:
(?<Q>[""'])(?<LOC>(?:(?!\<Q>).)*)\1
|
(?<LOC>[^""'/:]+)
) \s*
: \s* (?<LINE>\d+) \s*
/ \s* (?<YPOS>\d+)
", RegexOptions.IgnorePatternWhitespace);
foreach (string s in source)
{
Console.WriteLine(r2.Replace(s,
@"Location(${LOC}):LineNumber(${LINE})/YPosition(${YPOS})")
);
Console.WriteLine();
}
输出:
Location(TEST):LineNumber(4)/YPosition(6)
Location(12/03/03):LineNumber(4)/YPosition(6)
此正则表达式不会将空格视为分隔符,但它允许在字段值周围填充空格。它还将单引号和双引号字段与相同的构造进行匹配。在这种情况下,这并不值得额外的复杂性,但这是一种值得了解的技术。