【发布时间】:2020-10-04 02:46:23
【问题描述】:
更新:根据@Jack Misteli 的建议添加了@babel/plugin-transform-named-capturing-groups-regex 以查看 Babel。
更新:: 使用Babel 转换代码,然后我在@Jack Misteli 的CSB forked 中进行了测试。这里的关键是当我尝试返回groups 时,它是null
我正在尝试了解破坏此正则表达式的 Typescript(我的配置、语言等)是什么。
具体来说,它似乎与我使用的命名捕获组有关,因为当我删除它们时,它会起作用。
详情:
原始 TS 文件:
/**
*
* @param {string} markdownLink A link in the form of [title](link description)
* @returns {object} An object with three keys: title, link, description
*/
export function parseLink(markdownLink: string) {
const pattern: RegExp = new RegExp(
/^(\[(?<title>[^\]]*)?\]\((?<link>[A-Za-z0-9\:\/\.\- ]+)(?<description>\"(.+)\")?\))/
)
const match = markdownLink.match(pattern)
const groups = match?.groups
return groups
}
这转译为(添加 babel 插件后更新):
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.parseLink = parseLink;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapNativeSuper"));
function _wrapRegExp(re, groups) { _wrapRegExp = function _wrapRegExp(re, groups) { return new BabelRegExp(re, undefined, groups); }; var _RegExp = (0, _wrapNativeSuper2["default"])(RegExp); var _super = RegExp.prototype; var _groups = new WeakMap(); function BabelRegExp(re, flags, groups) { var _this = _RegExp.call(this, re, flags); _groups.set(_this, groups || _groups.get(re)); return _this; } (0, _inherits2["default"])(BabelRegExp, _RegExp); BabelRegExp.prototype.exec = function (str) { var result = _super.exec.call(this, str); if (result) result.groups = buildGroups(result, this); return result; }; BabelRegExp.prototype[Symbol.replace] = function (str, substitution) { if (typeof substitution === "string") { var groups = _groups.get(this); return _super[Symbol.replace].call(this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) { return "$" + groups[name]; })); } else if (typeof substitution === "function") { var _this = this; return _super[Symbol.replace].call(this, str, function () { var args = []; args.push.apply(args, arguments); if ((0, _typeof2["default"])(args[args.length - 1]) !== "object") { args.push(buildGroups(args, _this)); } return substitution.apply(this, args); }); } else { return _super[Symbol.replace].call(this, str, substitution); } }; function buildGroups(result, re) { var g = _groups.get(re); return Object.keys(g).reduce(function (groups, name) { groups[name] = result[g[name]]; return groups; }, Object.create(null)); } return _wrapRegExp.apply(this, arguments); }
/**
*
* @param {string} markdownLink A link in the form of [title](link description)
* @returns {object} An object with three keys: title, link, description
*/
function parseLink(markdownLink) {
var pattern = new RegExp( /*#__PURE__*/_wrapRegExp(/^(\[([\0-\\\^-\uFFFF]*)?\]\(([ \.-:A-Za-z]+)("(.+)")?\))/, {
title: 2,
link: 3,
description: 4
}));
var match = markdownLink.match(pattern);
var groups = match === null || match === void 0 ? void 0 : match.groups;
return groups;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ...fQ==
我的tsconfig 是:
{
"compilerOptions": {
/* Basic Options */
"target": "ESNext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
"sourceMap": true /* Generates corresponding '.map' file. */,
"outDir": "dist" /* Redirect output structure to the directory. */,
"composite": true /* Enable project compilation */,
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */,
/* Module Resolution Options */
"allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
/* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
"resolveJsonModule": true
},
"include": ["./src"]
}
我的.babelrc:
{
"presets": ["@babel/preset-env", "@babel/preset-typescript"],
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-runtime",
"@babel/plugin-transform-named-capturing-groups-regex"
]
}
值得注意的是这两种模式:
- 那个I wrote:
^(\[(?<title>[^\]]*)?\]\((?<link>[A-Za-z0-9\:\/\.\- ]+)(?<description>\"(.+)\")?\)) - 还有transpiled一个
/^(\[([\0-\\\^-\uFFFF]*)?\]\(([ \.-:A-Za-z]+)("(.+)")?\))/
不要不要做同样的事情(参见测试链接)。
如果我删除了命名的捕获组,它确实似乎有效,但我现在很难理解为什么我有一个复制完整的捕获组。
在上图中,您可以看到我将原生 JS 版本与导入的转译版本(来自 dist 文件夹)进行比较。
左边的调试器显示parsed的值,这是分配给转译版本返回的变量。
所以 - 我的问题:
- 我需要做些什么来启用 TS 中的命名捕获组吗? 更新 和 TS 无关,而是 Babel。答案是使用@babel/plugin-transform-named-capturing-groups-regex
- 有什么我应该知道的以了解为什么我得到了一个用于转译版本的重复组吗?
- 有没有更好的方法来做到这一点? :)
- 我在配置命名捕获组插件时做错了什么,当它存在时它仍然不返回匹配项?
【问题讨论】:
-
我不确定first link 是否与您发布的正则表达式匹配。
-
哎呀!谢谢@zzzzBov!固定。
标签: typescript babeljs