【问题标题】:Regex in JavaScript to process a URLJavaScript 中的正则表达式来处理 URL
【发布时间】:2017-09-23 23:57:23
【问题描述】:

我正在尝试编写正则表达式以匹配页面 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

【问题讨论】:

  • 您是否尝试过任何在线正则表达式编辑器?我个人用regex101.com,试试看。
  • | 运算符括起来有帮助吗?
  • @pratibha 我正在使用相同的。
  • @DavisHerring 我必须加括号。
  • 在任何 | 周围,您不想将整个 RE 划分为备选方案?

标签: javascript html regex regex-group


【解决方案1】:

建议

我建议你试试 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 方库,请检查这个具有类似用法的简单类。类构造函数创建模式,匹配方法返回结果,如果路径不匹配则返回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 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, '(?:$1)?')
                   .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;
  }
}

【讨论】:

  • 感谢@firanolfind,这是对我们的严格指导,不要使用任何第三方库。
  • 不错的答案。看起来url-patternexpress 在幕后的工作方式非常相似。作为记录,express 使用 path-to-regexp 代替。
  • 谢谢,@Firanolfind。
猜你喜欢
  • 2010-11-27
  • 2011-11-09
  • 2013-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
相关资源
最近更新 更多