位置: 编程技术 - 正文

XRegExp 0.2: Now With Named Capture

编辑:rootadmin

Update: A beta version of XRegExp 0.3 is now available as part of the RegexPal download package.

JavaScript's regular expression flavor doesn't support named capture. Well, says who? XRegExp 0.2 brings named capture support, along with several other new features. But first of all, if you haven't seen the previous version, make sure to check out my post on XRegExp 0.1, because not all of the documentation is repeated below.

HighlightsComprehensive named capture support (New) Supports regex literals through the addFlags method (New) Free-spacing and comments mode (x) Dot matches all mode (s) Several other minor improvements over v0.1 Named capture

There are several different syntaxes in the wild for named capture. I've compiled the following table based on my understanding of the regex support of the libraries in question. XRegExp's syntax is included at the top.

LibraryCaptureBackreferenceIn replacementStored atXRegExp(<name>…)k<name>${name}result.name.NET(?<name>…) (?'name'…) k<name> k'name' ${name}Matcher.Groups('name')Perl 5. (beta)(?<name>…) (?'name'…) k<name> k'name' g{name} $+{name}??Python(?P<name>…)(?P=name)g<name>result.group('name')PHP preg (PCRE)(.NET, Perl, and Python styles)$regs['name']$result['name']

No other major regex library currently supports named capture, although the JGsoft engine (used by products like RegexBuddy) supports both .NET and Python syntax. XRegExp does not use a question mark at the beginning of a named capturing group because that would prevent it from being used in regex literals (JavaScript would immediately throw an "invalid quantifier" error).

XRegExp supports named capture on an on-request basis. You can add named capture support to any regex though the use of the new "k" flag. This is done for compatibility reasons and to ensure that regex compilation time remains as fast as possible in all situations.

Following are several examples of using named capture:

// Add named capture support using the XRegExp constructorvar repeatedWords = new XRegExp("\b (<word> \w+ ) \s+ \k<word> \b", "gixk");// Add named capture support using RegExp, after overriding the native constructorXRegExp.overrideNative();var repeatedWords = new RegExp("\b (<word> \w+ ) \s+ \k<word> \b", "gixk");// Add named capture support to a regex literalvar repeatedWords = /b (<word> w+ ) s+ k<word> b/.addFlags("gixk");var data = "The the test data.";// Check if data contains repeated wordsvar hasDuplicates = repeatedWords.test(data);// hasDuplicates: true// Use the regex to remove repeated wordsvar output = data.replace(repeatedWords, "${word}");// output: "The test data."

In the above code, I've also used the x flag provided by XRegExp, to improve readability. Note that the addFlags method can be called multiple times on the same regex (e.g., /pattern/g.addFlags("k").addFlags("s")), but I'd recommend adding all flags in one shot, for efficiency.

Here are a few more examples of using named capture, with an overly simplistic URL-matching regex (for comprehensive URL parsing, see parseUri):

var url = " urlParser = new XRegExp("^(<protocol>[^:/?]+)://(<host>[^/?]*)(<path>[^?]*)\?(<query>.*)", "k");var parts = urlParser.exec(url);/* The result:parts.protocol: "http"parts.host: "microsoft.com"parts.path: "/path/to/file"parts.query: "q=1" */// Named backreferences are also available in replace() callback functions as properties of the first argumentvar newUrl = url.replace(urlParser, function(match){return match.replace(match.host, "yahoo.com");});// newUrl: " that XRegExp's named capture functionality does not support deprecated JavaScript features including the lastMatch property of the global RegExp object and the RegExp.prototype.compile() method.

Singleline (s) and extended (x) modes

The other non-native flags XRegExp supports are s (singleline) for "dot matches all" mode, and x (extended) for "free-spacing and comments" mode. For full details about these modifiers, see the FAQ in my XRegExp 0.1 post. However, one difference from the previous version is that XRegExp 0.2, when using the x flag, now allows whitespace between a regex token and its quantifier (quantifiers are, e.g., +, *?, or {1,3}). Although the previous version's handling/limitation in this regard was documented, it was atypical compared to other regex libraries. This has been fixed.

The code/* XRegExp 0.2.2; MIT LicenseBy Steven Levithan < support for the following regular expression features:- Free-spacing and comments ("x" flag)- Dot matches all ("s" flag)- Named capture ("k" flag) - Capture: (<name>...) - Backreference: k<name> - In replacement: ${name} - Stored at: result.name*//* Protect this from running more than once, which would break its references to native functions */if (window.XRegExp === undefined) {var XRegExp;(function () {var native = {RegExp: RegExp,exec: RegExp.prototype.exec,match: String.prototype.match,replace: String.prototype.replace};XRegExp = function (pattern, flags) {return native.RegExp(pattern).addFlags(flags);};RegExp.prototype.addFlags = function (flags) {var pattern = this.source,useNamedCapture = false,re = XRegExp._re;flags = (flags || "") + native.replace.call(this.toString(), /^[Ss]+//, "");if (flags.indexOf("x") > -1) {pattern = native.replace.call(pattern, re.extended, function ($0, $1, $2) {return $1 ? ($2 ? $2 : "(?:)") : $0;});}if (flags.indexOf("k") > -1) {var captureNames = [];pattern = native.replace.call(pattern, re.capturingGroup, function ($0, $1) {if (/^((?!?)/.test($0)) {if ($1) useNamedCapture = true;captureNames.push($1 || null);return "(";} else {return $0;}});if (useNamedCapture) {/* Replace named with numbered backreferences */pattern = native.replace.call(pattern, re.namedBackreference, function ($0, $1, $2) {var index = $1 ? captureNames.indexOf($1) : -1;return index > -1 ? "\" + (index + 1).toString() + ($2 ? "(?:)" + $2 : "") : $0;});}}/* If "]" is the leading character in a character class, replace it with "]" for consistentcross-browser handling. This is needed to maintain correctness without the aid of browser sniffingwhen constructing the regexes which deal with character classes. They treat a leading "]" within acharacter class as a non-terminating, literal character, which is consistent with IE, .NET, Perl,PCRE, Python, Ruby, JGsoft, and most other regex engines. */pattern = native.replace.call(pattern, re.characterClass, function ($0, $1) {/* This second regex is only run when a leading "]" exists in the character class */return $1 ? native.replace.call($0, /^([^?)]/, "$1\]") : $0;});if (flags.indexOf("s") > -1) {pattern = native.replace.call(pattern, re.singleline, function ($0) {return $0 === "." ? "[\S\s]" : $0;});}var regex = native.RegExp(pattern, native.replace.call(flags, /[sxk]+/g, ""));if (useNamedCapture) {regex._captureNames = captureNames;/* Preserve capture names if adding flags to a regex which has already run through addFlags("k") */} else if (this._captureNames) {regex._captureNames = this._captureNames.valueOf();}return regex;};String.prototype.replace = function (search, replacement) {/* If search is not a regex which uses named capturing groups, just run the native replace method */if (!(search instanceof native.RegExp && search._captureNames)) {return native.replace.apply(this, arguments);}if (typeof replacement === "function") {return native.replace.call(this, search, function () {/* Convert arguments[0] from a string primitive to a string object which can store properties */arguments[0] = new String(arguments[0]);/* Store named backreferences on the first argument before calling replacement */for (var i = 0; i < search._captureNames.length; i++) {if (search._captureNames[i]) arguments[0][search._captureNames[i]] = arguments[i + 1];}return replacement.apply(window, arguments);});} else {return native.replace.call(this, search, function () {var args = arguments;return native.replace.call(replacement, XRegExp._re.replacementVariable, function ($0, $1, $2) {/* Numbered backreference or special variable */if ($1) {switch ($1) {case "$": return "$";case "&": return args[0];case "`": return args[args.length - 1].substring(0, args[args.length - 2]);case "'": return args[args.length - 1].substring(args[args.length - 2] + args[0].length);/* Numbered backreference */default:/* What does "$" mean?- Backreference , if at least capturing groups exist- Backreference 1 followed by "0", if at least one capturing group exists- Else, it's the string "$" */var literalNumbers = "";$1 = +$1; /* Cheap type-conversion */while ($1 > search._captureNames.length) {literalNumbers = $1.toString().match(/d$/)[0] + literalNumbers;$1 = Math.floor($1 / ); /* Drop the last digit */}return ($1 ? args[$1] : "$") + literalNumbers;}/* Named backreference */} else if ($2) {/* What does "${name}" mean?- Backreference to named capture "name", if it exists- Else, it's the string "${name}" */var index = search._captureNames.indexOf($2);return index > -1 ? args[index + 1] : $0;} else {return $0;}});});}};RegExp.prototype.exec = function (str) {var result = native.exec.call(this, str);if (!(this._captureNames && result && result.length > 1)) return result;for (var i = 1; i < result.length; i++) {var name = this._captureNames[i - 1];if (name) result[name] = result[i];}return result;};String.prototype.match = function (regexp) {if (!regexp._captureNames || regexp.global) return native.match.call(this, regexp);return regexp.exec(this);};})();}/* Regex syntax parsing with support for escapings, character classes, and various other context and cross-browser issues */XRegExp._re = {extended: /(?:[^[#s\]+|\(?:[Ss]|$)|[^?]?(?:[^\]]+|\(?:[Ss]|$))*]?)+|(s*#[^nr]*s*|s+)([?*+]|{d+(?:,d*)?})?/g,singleline: /(?:[^[\.]+|\(?:[Ss]|$)|[^?]?(?:[^\]]+|\(?:[Ss]|$))*]?)+|./g,characterClass: /(?:[^\[]+|\(?:[Ss]|$))+|[^?(]?)(?:[^\]]+|\(?:[Ss]|$))*]?/g,capturingGroup: /(?:[^[(\]+|\(?:[Ss]|$)|[^?]?(?:[^\]]+|\(?:[Ss]|$))*]?|((?=?))+|((?:<([$w]+)>)?/g,namedBackreference: /(?:[^\[]+|\(?:[^k]|$)|[^?]?(?:[^\]]+|\(?:[Ss]|$))*]?|\k(?!<[$w]+>))+|\k<([$w]+)>(d*)/g,replacementVariable: /(?:[^$]+|$(?![1-9$&`']|{[$w]+}))+|$(?:([1-9]d*|[$&`'])|{([$w]+)})/g};XRegExp.overrideNative = function () {/* Override the global RegExp constructor/object with the XRegExp constructor. This precludes accessingproperties of the last match via the global RegExp object. However, those properties are deprecated asof JavaScript 1.5, and the values are available on RegExp instances or via RegExp/String methods. It alsoaffects the result of (/x/.constructor == RegExp) and (/x/ instanceof RegExp), so use with caution. */RegExp = XRegExp;};/* indexOf method from Mootools 1.; MIT License */Array.prototype.indexOf = Array.prototype.indexOf || function (item, from) {var len = this.length;for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++) {if (this[i] === item) return i;}return -1;};

You can download it, or get the packed version (2.7 KB).

XRegExp has been tested in IE 5.5?7, Firefox 2.0.0.4, Opera 9., Safari 3.0.2 beta for Windows, and Swift 0.2.

Finally, note that the XRE object from v0.1 has been removed. XRegExp now only creates one global variable: XRegExp. To permanently override the native RegExp constructor/object, you can now run XRegExp.overrideNative();

推荐整理分享XRegExp 0.2: Now With Named Capture,希望有所帮助,仅作参考,欢迎阅读内容。

XRegExp 0.2: Now With Named Capture

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

CLASS_CONFUSION JS混淆 全源码 利用随机字符串代替变量等,混淆原代码,保护自己写的代码,不利于别人直接剽窃SCRIPTlanguage=JavaScript!--/**//**//**//****============================================

mapper--图片热点区域高亮组件官方站点 很有意思的一个东西,我们都用过图片热点对多个切片做链接,也用过链接的hover高亮效果,但却没有办法实现图片热点的高亮效果(即鼠标悬停在某

DOMAssitant最新版 DOMAssistant 2.5发布 一个googlecode上的project刚发布了2.5版号称又要做一个大而全的js的库,要和jQuery,prototype,YUI,Ext对抗的,哈哈WiththisreleaseofDOMAssistant,Ifeelthatitcanseriouslycompetew

标签: XRegExp 0.2: Now With Named Capture

本文链接地址:https://www.jiuchutong.com/biancheng/386441.html 转载请保留说明!

上一篇:js定义对象简单学习例子(js中定义对象)

下一篇:CLASS_CONFUSION JS混淆 全源码

  • 残疾人就业保障金会计分录怎么做
  • 季度结转会计分录
  • 小规模纳税人租金发票开几个点
  • 计算消费税时运费计入计税依据么
  • 计提坏账又收回
  • 如何计算个别资金成本?
  • 让渡资产使用权收入的确认条件
  • 出口退税申报流程视频
  • 年底结账会计处理
  • 企业长期待摊费用包括
  • 审计部费用报销审计
  • 出售车辆需要缴纳哪些税
  • 特许权使用费分摊比例怎么算
  • 资本收益率的计算公式净资产收益率
  • 长期待摊费用账户按用途和结构分类应属于
  • 取得赔偿款的发票可以抵扣吗
  • 含税销售额的计算公式是什么意思
  • 增值税发票普票和专票有什么区别
  • 发票查询发票代码有误
  • 来料加工需要交税吗
  • 少计提增值税0.01计入营业外
  • 废旧物资收购发票
  • 多发的工资可以从下月扣除吗
  • 专家咨询费应如何支付
  • win11有什么升级
  • 收到退款的会计分录
  • 公司购买邮票计入什么科目
  • 银行支付的存款怎么做账
  • 差额征税账务处理规定
  • 代开的发票需要企业盖章还是税务机关盖章?
  • 西班牙的藏红花好不好
  • 拉帕努伊国家公园
  • 浅析是什么意思
  • Yii2使用swiftmailer发送邮件的方法
  • 块元素和行内元素区别
  • 基于php判断客户是否存在
  • lsmod命令结果详解
  • 电脑学word下哪个软件视频
  • 固定资产如何分类?
  • 可行性研究报告合同属于什么合同
  • 增值税进项加计抵减账务处理
  • 留言板系统php
  • 织梦怎么建站
  • sqlserver数据库作业
  • 小微企业的所得税税率是多少
  • 现金流量表的编制依据
  • 小规模纳税人未开票收入如何申报增值税
  • 土地使用权的核算
  • 无形资产摊销完以后得账务处理
  • 委托代销安排的迹象有哪些
  • 劳务简易征收最新政策2020
  • 汇算清缴业务招待费调整分录
  • 免征增值税账务处理办法
  • 高新技术企业进项税加计扣除10%如何填企业所得税季报
  • 服装厂委托物资怎么写
  • 过程中必须有哪两种状态
  • 小规模其他业务收入交多少税率
  • 进项税和销项税抵扣的会计分录
  • 如何学会计做账视频
  • 什么是计提坏账准备
  • 固定资产如何管理
  • 金融企业借款费用计入
  • bios 设置
  • win8.1 升级
  • ubuntu20.04命令
  • xp系统怎么删除电脑里所有东西
  • win10怎么把中文系统改成英文
  • scrtkfg.exe - scrtkfg是什么进程 有什么用
  • wire软件下载
  • input submit、button和回车键提交数据详解
  • css如何控制图片位置
  • perl语言基本命令
  • jquery的事件处理有哪些
  • android实现天气预报
  • android之handler
  • shell脚本实例精讲
  • pjblog修改技巧汇总
  • 新收入准则租赁业务
  • 云南省税务局咨询电话
  • 公车补贴计入工资吗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设