JavaScript 中的正则表达式来处理 URL

Regex in JavaScript to process a URL

我正在尝试编写正则表达式来匹配页面 URL

中数组单词的下方

例如 array = [schools,years,school,year,school-class,school-year,school-class-year,school-year-class,year-school, year-school -class]

页面url模式

http://www.google.com/search.html/{PATTERN}{/optional_String}

需要正则表达式
http://www.google.com/search.html/schools
http://www.google.com/search.html/years
http://www.google.com/search.html/year/2017
http://www.google.com/search.html/school/honda
https://www.google.com/search.html/year-school/2017/thomas
http://www.google.com/search.html/school-class/thomas/ClassA
http://www.google.com/search.html/school-year/thomas/2017
http://www.google.com/search.html/year-school-class/2017/thomas/ClassA
http://www.google.com/search.html/school-class-year/thomas/ClassA/2017
http://www.google.com/search.html/school-year-class/thomas/2017/ClassA

我是正则表达式的新手,尝试过以下但在许多测试用例中都失败了。

/(http|https):\/\/([\w\-\.]+)\/search.html\/(schools|years|school|year)|(school|year)-?(school|year|class)?-?(school|year|class)?-?(school|year|class)/g

建议

我建议你试试 nice lib url-pattern

var pattern = new UrlPattern('/year-school-class/:year/:school/:class');

var url = 'http://www.google.com/search.html/school-year-class/thomas/2017/ClassA'
var path = url.replace('www.google.com/search.html', '')
              .replace(/^\/\/|^.*?:(\/\/)?/, '');
// "/school-year-class/thomas/2017/ClassA"

pattern.match(path);
// {year: '2017', school: 'thomas', class: 'ClassA'}

没有第三方库

如果您不允许使用 3rd 方库,请检查这个简单的 class 以及类似的用法。 Class 构造函数创建模式,并匹配方法 returns 结果,如果路径不匹配 returns null。我从 Backbone.Router 中提取的基本逻辑。感谢 Backbone 团队。

JSBin Sample

用法

var pattern = '/year-school-class/:year/:school/:class(/:optional)';
var url = 'http://www.google.com/search.html/year-school-class/2017/thomas/ClassA'
//extract path
var path = url.replace('www.google.com/search.html', '')
              .replace(/^\/\/|^.*?:(\/\/)?/, '');
// "/school-year-class/thomas/2017/ClassA/"

var pattern = new PathPattern(pattern);
var params = pattern.match(path);
console.log(params);
// {year: '2017', school: 'thomas', class: 'ClassA', optional: null}

var params = pattern.match(path + '/someOptionalStuff');
console.log(params);
// {year: '2017', school: 'thomas', class: 'ClassA', optional: 'someOptionalStuff'}

Class源代码

class PathPattern{
  constructor(pattern){
    this.keys = [];
    var optionalParam = /\((.*?)\)/g;
    var namedParam    = /(\(\?)?:\w+/g;
    var splatParam    = /\*\w+/g;
    var escapeRegExp  = /[\-{}\[\]+?.,\\^$|#\s]/g;
    var route = pattern.replace(escapeRegExp, '\$&')
                   .replace(optionalParam, '(?:)?')
                   .replace(namedParam, (match, optional) => {
                     if(!optional)
                         this.keys.push(match.replace(/:/,''))
                     return optional ? match : '([^/?]+)';
                   })
                   .replace(splatParam, '([^?]*?)');
    this.rgx = new RegExp('^' + route + '(?:\?([\s\S]*))?$');
  }
  match(path){
    var params = {};
    var values = this.rgx.exec(path);
    if(!values) return null;
    values = values.slice(1);
    values = values.map((param, i)=>{
       if (i === values.length - 1) return param || null;
       return param ? decodeURIComponent(param) : null;
    });
    this.keys.forEach((key, i)=> params[key] = values[i]);
    return params;
  }
}