2013-02-27 2 views
-1

Я пытаюсь преобразовать часть Javascript в .NET, но я не могу понять, что все это правильно.Преобразование Javascript с регулярным выражением в C#

Это метод, который вызывается в Express для NodeJs. Он преобразует пути, такие как /test/:value1/:value2, в регулярное выражение, которое может использоваться на части URL.

/** 
* Normalize the given path string, 
* returning a regular expression. 
* 
* An empty array should be passed, 
* which will contain the placeholder 
* key names. For example "/user/:id" will 
* then contain ["id"]. 
* 
* @param {String|RegExp|Array} path 
* @param {Array} keys 
* @param {Boolean} sensitive 
* @param {Boolean} strict 
* @return {RegExp} 
* @api private 
*/ 

exports.pathRegexp = function(path, keys, sensitive, strict) { 
    if (path instanceof RegExp) return path; 
    if (Array.isArray(path)) path = '(' + path.join('|') + ')'; 
    path = path 
    .concat(strict ? '' : '/?') 
    .replace(/\/\(/g, '(?:/') 
    .replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/g, function(_, slash, format, key, capture, optional, star){ 
     keys.push({ name: key, optional: !! optional }); 
     slash = slash || ''; 
     return '' 
     + (optional ? '' : slash) 
     + '(?:' 
     + (optional ? slash : '') 
     + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' 
     + (optional || '') 
     + (star ? '(/*)?' : ''); 
    }) 
    .replace(/([\/.])/g, '\\$1') 
    .replace(/\*/g, '(.*)'); 
    return new RegExp('^' + path + '$', sensitive ? '' : 'i'); 
} 

Я попытался преобразовать его, в:

private Regex ConvertPathToRegex(string path, bool strict, out List<string> keys) { 

    keys = new List<string>(); 

    List<string> tempKeys = new List<string>(); 

    string tempPath = path; 

    if (strict) 
     tempPath += "/?"; 

    tempPath = Regex.Replace(tempPath, @"/\/\(", delegate(Match m) { 
     return "(?:/"; 
    }); 

    tempPath = Regex.Replace(tempPath, @"/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?", delegate(Match m) { 

     string slash = (!m.Groups[1].Success) ? "" : m.Groups[1].Value; 
     bool formatSuccess = m.Groups[2].Success; 
     string format = (!m.Groups[2].Success) ? "" : m.Groups[2].Value; 
     string key = m.Groups[3].Value; 
     bool captureSuccess = m.Groups[4].Success; 
     string capture = m.Groups[4].Value; 
     bool optional = m.Groups[5].Success; 
     bool star = m.Groups[6].Success; 

     tempKeys.Add(key); 

     string expression = "/"; 
     expression += (optional ? "" : slash); 
     expression += "(?:"; 
     expression += (optional ? slash : ""); 
     expression += (formatSuccess ? format : ""); 
     expression += (captureSuccess ? capture : (formatSuccess ? format + "([^/.]+?" : "([^/]+?)")) + ")"; 
     expression += (star ? "(/*)" : ""); 

     return expression; 
    }); 

    tempPath = Regex.Replace(tempPath, @"/([\/.])", @"\$1"); 
    tempPath = Regex.Replace(tempPath, @"/\*", "(.*)"); 
    tempPath = "^" + tempPath + "$"; 

    keys.AddRange(tempKeys); 

    return new Regex(tempPath, RegexOptions.Singleline | RegexOptions.IgnoreCase); 
} 

Но проблема в том, этот метод не работает правильно. Поскольку я не являюсь регулярным выражением суперзвезды, мне было интересно, смогу ли я помочь в этом.

Как-то метод завинчивается, когда вы также добавляете ?param=1.

EDIT: Это действительно хорошо работает, когда я сначала разбиваю параметры запроса на путь.

Извините, но ответ на вопрос состоял в том, чтобы просто удалить параметры запроса из URL-адреса.

+1

Можете ли вы подробно рассказать о «нерабочей» части. Приведите пример или около того. Кстати, это напоминает мне старую шутку: «У меня была проблема, и я попытался решить ее с помощью регулярного выражения. Теперь у меня две проблемы». –

+1

Ваш код выглядит странно. По правде говоря, .NET regex не нуждается в разделителе '' '' '' 'как в JS. – nhahtdh

ответ

0

Я сделал этот порт на PHP, возможно, он может помочь вам каким-то образом лучше понять, что делает экспресс, он возвращает регулярное выражение для соответствия параметрам.

<?php 
public static function pathRegexp($path, array &$keys, $sensitive = false, $strict = false) 
{ 
    if (is_array($path)) { 
     $path = '(' . implode('|', $path) . ')'; 
    } 

    $path = (($strict === true) ? $path : (rtrim($path, '/ ') . '/?')); 
    $path = preg_replace('/\/\(/', '(?:/', $path); 
    $path = preg_replace_callback('/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/', function($matches) use(&$keys) { 
       $slash = (isset($matches[1]) ? $matches[1] : ""); 
       $format = (isset($matches[2]) ? $matches[2] : false); 
       $key = (isset($matches[3]) ? $matches[3] : null); 
       $capture = (isset($matches[4]) ? $matches[4] : false); 
       $optional = (isset($matches[5]) ? $matches[5] : false); 
       $star = (isset($matches[6]) ? $matches[6] : false); 

       array_push($keys, array("name" => $key, "optional" => (!!$optional))); 

       return '' 
         . ($optional ? '' : $slash) 
         . '(?:' 
         . ($optional ? $slash : '') 
         . ($format ? $format : '') 
         . ($capture ? $capture : ($format ? '([^/.]+?)' : '([^/]+?)')) . ')' 
         . ($optional ? $optional : '') 
         . ($star ? '(/*)?' : ''); 
      }, $path); 
    $path = preg_replace('/([\/.])/', '\\/', $path); 
    $path = preg_replace('/\*/', '(.*)', $path); 
    $path = '/^' . $path . '$/' . ($sensitive ? '' : 'i'); 
    return $path; 
} 
Смежные вопросы