我要解析的字符串(又称消息)看起来像这样。 (当将其粘贴到记事本中时,它看起来也完全像这样
"CorrelationId: b99fb632-78cf-4910-ab23-4f69833ed2d9
Request for API: /api/acmsxdsreader/readpolicyfrompolicyassignment Caller:C2F023C52E2148C9C1D040FBFAC113D463A368B1 CorrelationId: b99fb632-78cf-4910-ab23-4f69833ed2d9 RequestedSchemas: {urn:schema:Microsoft.Rtc.Management.Policy.Voice.2008}VoicePolicy, {urn:schema:Microsoft.Rtc.Management.Policy.Voice.2008}OnlineVoiceRoutingPolicy, TenantId: 7a205197-8e59-487d-b9fa-3fc1b108f1e5"
我想制作5个单独的函数,以返回每个特定值,例如GetCorrelationId
,GetRFAPI
,GetCaller
,GetRqSchema
和{{1 }}并提取它们对应的值。
在不使用Regex的情况下如何在C#中执行此操作?
下面是我为调用者编写的代码(此方法对于所有其他4个函数都是相同的),但是我被告知正则表达式很慢,不应由我的指导者使用,而我下面的方法不会无论如何都没有工作。另外,我尝试使用正则表达式的最大问题是消息中有多个定界符,例如GetTenantId
',' ' ' and ': ' and ':'
预期结果应该是:
string parseCaller(string message)
{
var pattern = @"Caller:(.*)";
var r = new Regex(pattern).Match(message);
var caller = r.Groups[1].Value;
return caller;
}
答案 0 :(得分:3)
我会稍微有所不同,并创建一个类,该类具有要从字符串解析的每个值的属性。然后,我们可以创建一个静态Parse
方法,该方法从输入字符串创建该类的实例,从而为您设置所有属性。
如果字符串始终具有相同顺序的相同项目(CorrelationId,RequestForAPI,Caller等),我们可以利用简单的帮助程序方法来GetValueBetween
两个标头。
代码非常简单:
class MessageData
{
public string CorrelationId { get; set; }
public string RequestForAPI { get; set; }
public string RequestedSchemas { get; set; }
public string Caller { get; set; }
public string TennantId { get; set; }
public static MessageData Parse(string input)
{
return new MessageData
{
CorrelationId = GetValueBetween(input, "CorrelationId:", "Request for API:"),
RequestForAPI = GetValueBetween(input, "Request for API:", "Caller:"),
Caller = GetValueBetween(input, "Caller:", "CorrelationId:"),
RequestedSchemas = GetValueBetween(input, "RequestedSchemas:", "TenantId:"),
TennantId = GetValueBetween(input, "TenantId:", null),
};
}
private static string GetValueBetween(string input, string startDelim, string endDelim)
{
if (input == null) return string.Empty;
var start = input.IndexOf(startDelim);
if (start == -1) return string.Empty;
start += startDelim.Length;
var length = endDelim == null
? input.Length - start
: input.IndexOf(endDelim, start) - start;
if (length < 0) length = input.Length - start;
return input.Substring(start, length).Trim();
}
}
现在我们可以调用MessageData.Parse(inputString)
,我们有了一个类,它的所有属性都通过输入字符串设置:
private static void Main()
{
var message = @"CorrelationId: b99fb632-78cf-4910-ab23-4f69833ed2d9
Request for API: /api/acmsxdsreader/readpolicyfrompolicyassignment Caller:C2F023C52E2148C9C1D040FBFAC113D463A368B1 CorrelationId: b99fb632-78cf-4910-ab23-4f69833ed2d9 RequestedSchemas: {urn:schema:Microsoft.Rtc.Management.Policy.Voice.2008}VoicePolicy, {urn:schema:Microsoft.Rtc.Management.Policy.Voice.2008}OnlineVoiceRoutingPolicy, TenantId: 7a205197-8e59-487d-b9fa-3fc1b108f1e5";
var messageData = MessageData.Parse(message);
// Now we can access any property
Console.WriteLine(messageData.CorrelationId);
Console.WriteLine(messageData.RequestForAPI);
Console.WriteLine(messageData.RequestedSchemas);
Console.WriteLine(messageData.Caller);
Console.WriteLine(messageData.TennantId);
Console.ReadKey();
}
答案 1 :(得分:1)
根据您提出的问题中的这些规范:
在不使用Regex的情况下如何在C#中执行此操作?
和
我想做5个独立的功能
您可以尝试以下方法。这非常简单,因为您可以研究字符串并适当使用IndexOf
和SubString
函数:
using System;
class ParseTest
{
static string GetCorrelationId(string message)
{
int i = message.IndexOf(": ") + 2; //length of ": "
int j = message.IndexOf("Request");
return message.Substring(i, j-i).Trim();
}
static string GetRFAPI(string message)
{
int i = message.IndexOf("API: ") + 5; //length of "API: "
int j = message.IndexOf("Caller");
return message.Substring(i, j-i).Trim();
}
static string GetCaller(string message)
{
int i = message.IndexOf("Caller:") + 7; //length of "Caller: "
int j = message.IndexOf(" CorrelationId");
return message.Substring(i, j-i).Trim();
}
static string GetRqSchema(string message)
{
int i = message.IndexOf("RequestedSchemas:") + 17; //length of "RequestedSchemas:"
int j = message.IndexOf(", TenantId:");
return message.Substring(i, j-i).Trim();
}
static string GetTenantId(string message)
{
int i = message.IndexOf("TenantId:") + 9; //length of "TenantId: "
return message.Substring(i).Trim();
}
static void Main()
{
string m = @"CorrelationId: b99fb632-78cf-4910-ab23-4f69833ed2d9
Request for API: /api/acmsxdsreader/readpolicyfrompolicyassignment Caller:C2F023C52E2148C9C1D040FBFAC113D463A368B1 CorrelationId: b99fb632-78cf-4910-ab23-4f69833ed2d9 RequestedSchemas: {urn:schema:Microsoft.Rtc.Management.Policy.Voice.2008}VoicePolicy, {urn:schema:Microsoft.Rtc.Management.Policy.Voice.2008}OnlineVoiceRoutingPolicy, TenantId: 7a205197-8e59-487d-b9fa-3fc1b108f1e5";
Console.WriteLine(GetCorrelationId(m));
Console.WriteLine(GetRFAPI(m));
Console.WriteLine(GetCaller(m));
Console.WriteLine(GetRqSchema(m));
Console.WriteLine(GetTenantId(m));
}
}
您可以here运行它。
编辑:当然,您可以将其修改为使用仅获取属性,就像其他一些回答者试图做的那样。
另一方面,如果您想编写一个解析器(这是一个懒惰的人?),那么您的研究乐趣又是另一回事。
答案 2 :(得分:1)
如果您不知道将来从API返回的这些元素的顺序是否会更改,这是一个更可靠的解决方案:
private string GetRFAPI(string str)
{
return GetSubstring(str, "Request for API: ", ' ', 1);
}
private string GetCaller(string str)
{
return GetSubstring(str, "Caller:", ' ', 1);
}
private string GetCorrelationId(string str)
{
return GetSubstring(str, "CorrelationId: ", ' ', 1);
}
private string GetTenantId(string str)
{
return GetSubstring(str, "TenantId: ", ' ', 1);
}
private string GetRequestedSchemas(string str)
{
return GetSubstring(str, "RequestedSchemas: ", ',', 2);
}
private string GetSubstring(string str, string pattern, char delimiter, int occurrence)
{
int start = str.IndexOf(pattern);
if (start < 0)
{
return null;
}
for (int i = start + pattern.Length, counter = 0; i < str.Length; i++, counter++)
{
if ((str[i] == delimiter && --occurrence == 0) || i == str.Length - 1)
{
return str.Substring(start + pattern.Length, counter).Trim();
}
}
return null;
}