我正在编写一个从System.Type.FullName(不是XML)中删除名称空间的方法。
我开始搜索,并没有得到太多,所以切换到尝试写一个正则表达式,我可以使用一个Regex. replace()。但我远不是一个精通正则表达式艺术的大师,所以我谦卑地在正则表达式之神面前展示自己。
给定以下输入:
name.space.class
name.space.class<other.name.space.class1>
name.space.class<other.name.space.class1, shortSpace.class2>
我需要删除命名空间,所以我得到:
class
class<class1>
class<class1, class2>
或者,如果有人知道现有的库具有此功能,那就更好了!
注:我知道系统。Type有一个Namespace属性,我可以用它来删除命名空间(例如System.Type.FullName - System.Type.Namespace),但是我的方法将类型名称作为字符串,并且需要处理运行时不知道的类型名称(无法解析)。
这个怎么样?
[.w]+.(w+)
…代入$1
。查看regex101上的操作。
从一些c#的例子来看,似乎你会做
string output = Regex.Replace(input, @"[.w]+.(w+)", "$1");
试试这个:
public static string RemoveNamespaces(string typename)
{
return string.Join("",
Regex.Split(typename,
@"([^w.])").Select(p =>
p.Substring(p.LastIndexOf('.') + 1)));
}
我甚至不会考虑使用正则表达式。这里的命令式代码非常简单,尽管它需要一点string-fu:
public string RemoveNamespace(string typename)
{
if(typename.Contains("<")
{
var genericArguments =
typename.
// in reality, we need a substring before
// first occurence of "<" and last occurence of ">"
SubstringBetween("<", ">").
Split(',').
Select(string.Trim).
Select(RemoveNamespace);
return
RemoveNamespace(typename.SubstringBefore("<")) +
"<" +
string.Join(", ", genericArguments) +
">";
}
else
{
return typename.Trim().SubstringAfterLastOccurenceOf(".");
}
}
听起来像是使用正面展望的好情况:
(w+[.+])+(?=w+)
此模式将匹配以句号或加号分隔的任何数量的单词,序列中的最后一个(类型的短名称)除外。用空字符串替换匹配项将删除所有命名空间前缀。
为什么不按点(.)分割,只取最后一个字符串