正则表达式是你的朋友。它们是为切片和切割文本而设计的。这是一个可以满足您需要的课程:
class MyDecodedUri
{
// regex to match strings like this: /cat-phone/cat-samsung/attrib-1_2/attrib-2_88/...
const string PathSegmentRegex = @"
/ # a solidus (forward slash), followed by EITHER
( # ...followed by EITHER
(?<cat> # + a group named 'cat', consisting of
cat # - the literal 'cat' followed by
- # - exactly 1 hyphen, followed by
(?<catName>\p{L}+) # - a group named 'catName', consisting of one or more decimal digits
) | # OR ...
(?<attr> # + a group named 'attr', consisting of
attrib # - the literal 'attrib', followed by
- # - exactly 1 hyphen, followed by
(?<majorValue>\d+) # - a group named 'majorValue', consisting of one or more decimal digits, followed by
_ # - exactly one underscore, followed by
(?<minorValue>\d+) # - a group named 'minorValue', consisting of one or more decimal digits
) #
) #
" ;
static Regex rxPathSegment = new Regex( PathSegmentRegex , RegexOptions.ExplicitCapture|RegexOptions.IgnorePatternWhitespace ) ;
public MyDecodedUri( Uri uri )
{
Match[] matches = rxPathSegment.Matches(uri.AbsolutePath).Cast<Match>().Where(m => m.Success ).ToArray() ;
this.categories = matches
.Where( m => m.Groups["cat"].Success )
.Select( m => new UriCategory( m.Groups["catName"].Value ) )
.ToArray()
;
this.attributes = matches
.Where( m => m.Groups["attr"].Success )
.Select( m => new UriAttribute( m.Groups["majorValue"].Value , m.Groups["minorValue"].Value ) )
.ToArray()
;
return ;
}
private readonly UriCategory[] categories ;
public UriCategory[] Categories { get { return (UriCategory[]) categories.Clone() ; } }
private readonly UriAttribute[] attributes ;
public UriAttribute[] Attributes { get { return (UriAttribute[]) attributes.Clone() ; } }
public Uri RawUri { get ; private set ; }
}
它使用了几个自定义帮助器类型,一个用于类别,一个用于属性:
struct UriCategory
{
public UriCategory( string name ) : this()
{
if ( string.IsNullOrWhiteSpace(name) ) throw new ArgumentException("category name can't be null, empty or whitespace","name");
this.Name = name ;
return ;
}
public readonly string Name ;
public override string ToString() { return this.Name ; }
}
struct UriAttribute
{
public UriAttribute( string major , string minor ) : this()
{
bool parseSuccessful ;
parseSuccessful = int.TryParse( major , out Major ) ;
if ( !parseSuccessful ) throw new ArgumentOutOfRangeException("major") ;
parseSuccessful = int.TryParse( minor , out Minor ) ;
if ( !parseSuccessful ) throw new ArgumentOutOfRangeException("minor") ;
return ;
}
public readonly int Major ;
public readonly int Minor ;
public override string ToString() { return string.Format( "{0}_{1}" , this.Major , this.Minor ) ; }
}
用法非常简单:
string url = "http://www.sample.com/cat-phone/cat-samsung/attrib-1_2/attrib-2_88/" ;
Uri uri = new Uri(url) ;
MyDecodedUri decoded = new MyDecodedUri(uri) ;