我需要创建扩展方法来解析(拆分)我的字符串。
例如: 如果我有字符串
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;
}
我想实施更清洁的解决方案。有什么想法吗?
答案 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
|
:
答案 2 :(得分:0)
您可以使用正则表达式:([^\s"]+|"[^"]*")
和全球标识符
答案 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。