下面的代码运行良好,目标是在XML文件中查找GUID字符串。因此它会找到字符串A03DD607-90BF-4077-ADA8-C6E76F9D4759
,但现在我正在尝试将正则表达式更改为仅查找:
id="A03DD607-90BF-4077-ADA8-C6E76F9D4759"
而不是
A03DD607-90BF-4077-ADA8-C6E76F9D4759
这是我的代码:
//obtain all GUIDs in the XML file
using (StreamReader sr = File.OpenText(xmlFile))
{
string s = String.Empty;
while ((s = sr.ReadLine()) != null)
{
MatchCollection guids = Regex.Matches(s, @"(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}");
for (int i = 0; i < guids.Count; i++)
{
Console.WriteLine(guids[i].Value);
guidList.Add(guids[i].Value.ToUpper());
}
}
}
答案 0 :(得分:1)
我会将文字Guid
的识别推迟到Guid.TryParse()
。这会使你的正则表达式减少到这样:
private const RegexOptions rxOptions = RegexOptions.IgnoreCase
| RegexOptions.ExplicitCapture
| RegexOptions.CultureInvariant
;
private static readonly Regex rxGuidId = new Regex( @"id=""(?<guid>[^""]+)""", rxOptions );
然后你可以在LINQ中完成所有操作,就像这样:
private static Guid[] ExtractGuidsFromText( string s )
{
return rxGuidId
.Matches( s ?? "" )
.Cast<Match>()
.Where( m => m.Success )
.Select( m => {
Guid instance;
bool validGuid = Guid.TryParse( m.Groups["guid"].Value , out instance ) ;
return validGuid ? (Guid?)instance : (Guid?)null ;
})
.Where( g => g.HasValue )
.Select( g => g.Value )
.ToArray()
;
}
LINQ解决方案比直接,简单的方式更简洁,更优雅,更慢并且使用更多内存:
private static IEnumerable<Guid> ExtractGuidsFromText( string s )
{
for ( Match m = rxGuidId.Match( s ?? "" ) ; m.Success ; m = m.NextMatch() )
{
Guid instance;
bool parsed = Guid.TryParse( m.Groups["guid"].Value , out instance ) ;
if ( parsed ) yield return instance;
}
}
但是既然你有一个XML文件,你当然可以使用内置的.Net支持XML,并通过Xpath(//@id
)选择你的节点集应该这样做,只是丢弃那些没有有效GUID的节点。
或者您可以使用XML阅读器并懒洋洋地找到它们:
static IEnumerable<string> ReadGuidsFromXml( TextReader input )
{
using ( XmlReader reader = XmlReader.Create( input ) )
{
while ( reader.Read() )
{
if ( reader.NodeType != XmlNodeType.Element ) continue ;
for ( bool hasAttributes = reader.MoveToFirstAttribute() ; hasAttributes ; hasAttributes = reader.MoveToNextAttribute() )
{
if ( !string.Equals( reader.Name , "id" , StringComparison.OrdinalIgnoreCase ) ) continue ;
Guid guid;
if ( Guid.TryParse( reader.Value , out guid ) )
{
yield return guid;
}
}
}
}
}
答案 1 :(得分:0)
您可以使用以下代码替换相应的代码行:
MatchCollection guids = Regex.Matches(s, @"id=""(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}""");
在C#字符串文字中,文字引号必须加倍。