Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Regex.Split-希望用字符分割字符串,但允许在';和';_C#_Regex - Fatal编程技术网

C#Regex.Split-希望用字符分割字符串,但允许在';和';

C#Regex.Split-希望用字符分割字符串,但允许在';和';,c#,regex,C#,Regex,我希望通过/拆分字符串,但也允许'和'之间的任何内容包含拆分字符。从拆分和任何空格中删除'和' 示例/'TEST/:1'/3分为 Test/:1 3 我有一件事很接近: regex.split(test, "/(?=(?:[^']*'[^']*')*[^']*$)" 但是它仍然有”和空格 string[] fields = Regex.Split(Path, "/(?=(?:[^']*'[^']*')*[^']*$)"); 抱歉,我会更清楚它是我自己的路径格式,用于解析类似EDI的文件

我希望通过
/
拆分字符串,但也允许
'
'
之间的任何内容包含拆分字符。从拆分和任何空格中删除
'
'

示例
/'TEST/:1'/3
分为

  • Test/:1
  • 3
我有一件事很接近:

regex.split(test, "/(?=(?:[^']*'[^']*')*[^']*$)" 
但是它仍然有
和空格

string[] fields = Regex.Split(Path, "/(?=(?:[^']*'[^']*')*[^']*$)");
抱歉,我会更清楚它是我自己的路径格式,用于解析类似EDI的文件,它的工作原理如下<代码>/位置:行号/Y位置。我只想进入命令行
/TEST:4/6=/Location(TEST):LineNumber(4)/YPosition(6)
。但我的问题是,位置是由我的代码计算出来的,可以是第一个分隔符之前的任何内容。它可以是EDI类型文件中常见的日期格式
12/03/03

我希望能够使我的命令看起来像这样
/'12/03/03':4/6
,这样当位置被我的regex.split分割时,它不包括('and')位置之间的任何内容


有什么帮助吗?

不完全清楚您真正想要实现的目标。如果您想解析类似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
,因为空格会被删除,因此也可以用作分隔符。

您真正想要实现的目标并不完全清楚。如果您想解析类似CSV的文件格式,最好使用CSV解析器;如果要操纵文件路径,请使用标准库的路径操纵函数。两者都比简单的正则表达式更适合处理边缘情况

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);

        }


    }
也就是说,你可以做到

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
,因为空格被删除,因此也可以用作分隔符。

类程序
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);

        }


    }
{ 静态void Main(字符串[]参数) { 字符串输入=“\”\“\”/one/\“two/three-four\”/five/”; var分隔符=“/”; var empty=“(?\\s*)”; var word=string.Format((?[^{0}]+),分隔符); var quotedWord=“(?[^\\\”]+)”; var token=string.Format((\”({0}{1})\”)({0}}{2})),空,引号单词,单词); var pattern=string.Format(“({0}/)+({0})”,token); foreach(Regex.Match(输入,模式)中的变量捕获。组[“word”]。捕获) 控制台写入线(捕获); } }
课程计划
{
静态void Main(字符串[]参数)
{
字符串输入=“\”\“\”/one/\“two/three-four\”/five/”;
var分隔符=“/”;
var empty=“(?\\s*)”;
var word=string.Format((?[^{0}]+),分隔符);
var quotedWord=“(?[^\\\”]+)”;
var token=string.Format((\”({0}{1})\”)({0}}{2})),空,引号单词,单词);
var pattern=string.Format(“({0}/)+({0})”,token);
foreach(Regex.Match(输入,模式)中的变量捕获。组[“word”]。捕获)
控制台写入线(捕获);
}
}

拆分
并不是这类工作的正确工具。如果只使用斜杠进行拆分,那就可以了,但是添加可选引号后,匹配字段比匹配分隔符要容易得多。下面是一个正则表达式,它允许使用单引号或双引号字符串,并将
/
和空格作为分隔符:

  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();
  }
重复使用
字段
组名可以很容易地删除字段中的引号。这里有一种更“语义”的方法,它在一次传递中匹配整个字符串,并使用命名组将字段值归档。我只是将它们插入替换字符串中,但是您可以使用
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();
  }

此正则表达式不将空格视为分隔符,但它允许在字段值周围填充空格。它还匹配具有相同构造的单引号和双引号字段。在这种情况下,这并不值得付出额外的复杂性,但这是一种值得了解的技术。

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();
  }
重复使用
字段
组名可以很容易地删除字段中的引号。这里有一种更“语义”的方法,它在一次传递中匹配整个字符串,并使用命名组将字段值归档。我只是将它们插入替换字符串中,但是您可以使用
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();
  }
此正则表达式不将空格视为分隔符,但它允许在字段值周围填充空格。它还匹配具有相同构造的单引号和双引号字段。在这种情况下,这并不值得付出额外的复杂性,但这是一种技术