使用正则表达式

时间:2016-08-01 08:36:11

标签: c# regex split

我需要创建扩展方法来解析(拆分)我的字符串。

例如: 如果我有字符串

  

COMMAND 1 PROCESSED" JOB命令" 20160801 09:05:24

它应该像这样分开

  

COMMAND

     

1

     

加工

     

" JOB命令"

     

20160801

     

9时05分24秒

其他例子。 如果我有字符串:

  

COMMAND 2 ERROR 06 00000032"消息窗口仍然有效。" 20160801   9时05分24秒

它应该像这样分开:

  

COMMAND

     

2

     

ERROR

     

06

     

00000032

     

"消息窗口仍处于活动状态。"

     

20160801 09:05:24

我有解决方案。但我相信有更清洁的解决方案。

我的解决方案:

 public static List<string> GetTokens(this string line)
        {
            // TODO: Code refactoring:
            var res = new List<string>();
            var parts = Regex.Split(line, "/[^\\s\"']+|\"([^\"]*)\"|'([^']*)'/g");

            var subParts = parts[0].Split(' ');
            foreach (var val in subParts)
            {
                res.Add(val);
            }
            res.Add(parts[1]);
            subParts = parts[2].Split(' ');
            foreach (var val in subParts)
            {
                res.Add(val);
            }

            res.RemoveAll(f => f.Trim() == "");
            return res;
        }

我想实施更清洁的解决方案。有什么想法吗?

4 个答案:

答案 0 :(得分:4)

我建议实现简单循环而不是复杂正则表达式

public static IEnumerable<String> GetTokens(this string value) {
  if (string.IsNullOrEmpty(value))
    yield break; // or throw exception in case of value == null

  bool inQuotation = false;
  int index = 0;

  for (int i = 0; i < value.Length; ++i) {
    char ch = value[i];

    if (ch == '"')
      inQuotation = !inQuotation;
    else if ((ch == ' ') && (!inQuotation)) {
      yield return value.Substring(index, i - index);

      index = i + 1;
    }
  }

  if (index < value.Length)
    yield return value.Substring(index, value.Length - index);
}

测试

var source = 
  "COMMAND 2 ERROR 06 00000032 \"Message window is still active.\" 20160801 09:05:24";

Console.Write(string.Join(Environment.NewLine, GetTokens(source)));

输出

 COMMAND
 2
 ERROR
 06
 00000032
 "Message window is still active."
 20160801
 09:05:24

修改:如果您需要两种带"(双)的引用类型以及'(单一):

public static IEnumerable<String> GetTokens(string value) {
  if (string.IsNullOrEmpty(value))
    yield break;

  bool inQuotation = false;
  bool inApostroph = false;

  int index = 0;

  for (int i = 0; i < value.Length; ++i) {
    char ch = value[i];

    if (inQuotation) 
      inQuotation = ch != '"';
    else if (inApostroph) 
      inApostroph = ch != '\'';
    else if (ch == '"')
      inQuotation = true;
    else if (ch == '\'')
      inApostroph = true;
    else if ((ch == ' ') && (!inQuotation)) {
      yield return value.Substring(index, i - index);

      index = i + 1;
    }
  }

  if (index < value.Length)
    yield return value.Substring(index, value.Length - index);
}

答案 1 :(得分:1)

过了一会儿,他想出了一些简单的代码:

public static List<string> GetTokens(this string line)
{
    return Regex.Matches(line, @"([^\s""]+|""([^""]*)"")").OfType<Match>().Select(l => l.Groups[1].Value).ToList();
}

我使用MessageBox对代码进行了测试,结果显示每个项目之间都有List |

enter image description here

答案 2 :(得分:0)

您可以使用正则表达式:([^\s"]+|"[^"]*")和全球标识符

Demo and Explaination

答案 3 :(得分:0)

纯正的正则表达式解决方案:

import java.net.*;
import java.io.*;

public static boolean isFileExist(String URLName){
    try {
        HttpURLConnection.setFollowRedirects(false);
        //you may also need HttpURLConnection.setInstanceFollowRedirects(false)
        HttpURLConnection con =
                (HttpURLConnection) new URL(URLName).openConnection();
        con.setRequestMethod("HEAD");
        return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
    }
    catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

".*?"|\S+正则表达式匹配带引号的字符串或非空格字符序列。然后可以一次性将这些匹配作为集合返回。

以下是演示:https://ideone.com/hmLQIt