2016-08-27 5 views
-1

現在、指定されたURLの列を持つCSVを実行しています。UriBuilderで間違った構造のURLをフォーマットするには?

私は、URLを使用して特定のエンドポイントからデータを取得しています。

私の現在の方法は私のエンドポイントに送信するために、URIのホストを解析することですが、次のされています

URLがひどくによるヒューマンエラーに型指定された/構造化/フォーマットする可能性を秘めているが
public static Uri GetURI(string s) 
{ 
    return new UriBuilder(s).Uri; 
} 

if (websiteLoc > -1) { 
    if(!String.IsNullOrEmpty(row[websiteLoc])) 
    { 
     Uri uri = GetURI(row[websiteLoc]); 
     record.Add("website", uri.Host); 
    } else { 
     record.Add("website", ""); 
    } 
} 

URLを入力する人々の私のコードが誤って正しいホストを解析またはエラーをスローしたいずれかのこれらの事例では

htpp://www.sessler.cm.utexas.edu/ 
http //www.fedex.com 
http.redhead-int.com 
http:://www.741limo.com/ 

アイブ氏は、次のような列では極めて不十分にフォーマットのURLに実行します。これらの恐ろしいURLを正しく解析するより良い方法はありますか?

答えて

0

あなたはUri.IsWellFormedUriString(に依存している場合は、偽陰性/陽性のトンを得るでしょう)、しかし...

あなたはまた、あなたを高めるためにしようとするREGEXおよび/または文字列の比較を組み合わせて使用​​することができます有効なURLヒット率。私はRegexがもっと良いかもしれないいくつかの場所でchar比較を使用することに注意してください。私はあなたがREGEXか直接比較のどちらかを行うことができることを示しています。

REGEXやロジックを追加すれば、より良い結果が得られる可能性があります。これは100%のヒット率を生成しませんが、タイプの悪いURLの数をクリーンアップします。正規表現はSystem.Text.RegularExpressionsへの参照が必要なことに注意してください:

private List<int> acceptableChars = new List<int>(); 
    private void createListOfAcceptableCharacters() 
    { 

     List<int> acceptableChars = new List<int>(); 
     acceptableChars.Add(45);// - 
     acceptableChars.Add(46);// . 
     acceptableChars.Add(47);///
     for (int a = 97; a < 123; a++) 
     {// a through z 
      acceptableChars.Add(a); 
     } 
     for (int a = 48; a < 58; a++) 
     {//0 through 9 
      acceptableChars.Add(a); 
     } 
    } 
    public string parseURL(string input) 
    {//you would only do this once in reality 
     createListOfAcceptableCharacters(); 
     //basic cleanup 
     input = input.ToLower(); 
     //Regex.Replace would be more elegant here but string.replace works, too 
     input = input.Replace(".cm", ".com").Replace("htpp","http").Replace("htp", "http").Replace("http.", "http:").Replace("//ww.", "//www.").Replace(":/", "://").Replace(":////", "://").Replace(":///", "://").Replace(" ",""); 
     //check to see if URL is generally valid as-is 
     bool isValid = isValidURL(input); 
     if (isValid) 
     { 
      return input; 
     } 
     //try to salvage a poorly formed URL 
     bool isSecure = input.Substring(0, 5).IndexOf("https") > -1 ? true : false; 
     input = input.Replace(" ","").Replace(":","").Replace("https","").Replace("http//", "").Replace("http/", "").Replace("http", "").Replace("http", "").Replace("//","").Replace("www","").Replace("ww","").Replace("cm","com");//again, regex.replace would be more elegant 
     //clear front end to first period if it exists before space 6 
     if (input.IndexOf(".") < 7) 
     { 
      int period = input.IndexOf("."); 
      input = input.Substring(period+1); 
     } 
     //get the extension 
     string extension = ""; 
     if (input.Substring(input.Length - 1) == "/") 
     { 
      input = input.Substring(0, input.Length - 1); 
     } 
     if (input.Substring(input.Length - 4, 1) == ".") 
     { 
      //extension is where we expect 
      extension = input.Substring(input.Length - 3, 3); 
      input = input.Replace("." + extension, ""); 
     }else 
     { 
      //cannot find extension - can't process 
      return "badURL"; 
     } 
     string url = ""; 
     //move backwars through path, collecting only acceptable characters (note, this can be done with REGEX as well) 
     for (int i = input.Length-1; i > -1; i--) 
     { 
      string thisChar = input.Substring(i, 1); 
      if (thisChar == ":") 
      { 
       return "http://" + url + "." + extension; 
      } 
      int utf = (int)Convert.ToChar(thisChar); 

      //compare current char to list of acceptable chars 
      if (acceptableChars.Contains(utf)) 
      { 
       url = thisChar+url; 
      } 

     } 
     //final cleanup and full path formation 
     if (url.Substring(0, 1) == ".") 
     { 
      url = url.Substring(1); 
     } 
     url = isSecure ? "https://" : "http://" + url + "." + extension; 
     //optional 
     url = isSecure ? "https://www." : "http://www." + url + "." + extension; 
     url = url.Replace("::", ":"); 
     //test salvaged url. If reasonable, return else return badURL 
     if (isValidURL(url)) 
     { 
      return url; 
     }else 
     { 
      return "badURL"; 
     } 


    } 

    private bool isValidURL(string url) 
    { 
     bool isValid = Regex.IsMatch(url, @"^((http[s]?:[/][/])?(\w+[\-.])+com|((http[s]?:[/][/])?(\w+[\-.])+com[/]|[.][/])?\w+([/]\w+)*([/]|[.]html|[.]php|[.]gif|[.]jpg|[.]png)?)$"); 
     return isValid; 

    } 

私の代わりに「BADURL」の「固定」のURLを返すように解析方法を改正提案するかもしれない - 時にはそれが実際にあるURLを修正します正当なものですが、RegExによる誤った拒絶を受けます。 「badURL」の戻り値を処理するのではなく、URLにアクセスしてエラーを処理できます。

ご注意ください - これは決して最終的な解決策を示すものではありません。複数の入力をテストして修正し、それに応じてコードをクリーン/最適化する必要があります。これは、文字列の比較とRegexの両方を使用してURLをクリーンアップすることを実証するための例としてのみ意図されています。

関連する問題