Javascript 正则表达式 - 如何在组内查找 PascalCase 项
Javascript regex- How to find PascalCase items inside of group
我需要像这样转换:
[[Click here|ThisIsALink]]
至:
[Click here](https://example.com/this-is-a-link)
我可以通过使用此正则表达式 /\[\[(.*?)\|(.*?)\]\]/g
找到第一个 [[Click here|ThisIsALink]]
,我可以将其替换为 [Click here](https://example.com/ThisIsALink])
,但是我该如何处理最后一部分并将其转换为 this-is-a-link
?我已经尝试了一些事情,但我似乎找到了所有 PascalCased 事件,而不仅仅是在第一个找到的正则表达式模式中发生的事件。 (我正在将 .md 文件转换为 .pdf,所以它是一整页的内容,而不仅仅是这些链接)。
这是我目前所拥有的
var exampleUrl = "https://example.com/";
var urlOne = /\[\[(.*?)\|(.*?)\]\]/g;
data.replace(urlOne, "[](" + exampleUrl + ")"));
这导致:
[Click here](https://example.com/ThisIsALink)
您可以使用
const texts = ["Text [[Click here|ThisIsALink]] text...",
"Text [[Click here|This-Is-A-Link]] text..."];
const exampleUrl = "https://example.com/";
const urlOne = /\[\[((?:(?!\[\[).)*?)\|(.*?)]]/g;
for (var text of texts) {
console.log(
text.replace(urlOne, (_,x,y) =>
`[${x}](${exampleUrl}${y.replace(/[^A-Za-z]+/g, '')
.replace(/(?!^)[A-Z]/g, '-$&')
.toLowerCase()})`) );
}
正则表达式 #1 详细信息:
\[\[
- [[
字符串
((?:(?!\[\[).)*?)
- 第 1 组:除换行符以外的任何字符,零次或多次,尽可能少,不开始 [[
字符序列
\|
- 一个 |
字符
(.*?)
- 第 2 组:除换行字符外的任何零个或多个字符,尽可能少
]]
- ]]
字符串。
第二个正则表达式、(?!^)[A-Z]
应用于第 2 组内容,并匹配任何不在字符串开头的大写 ASCII 字母。 -$&
替换只是在匹配之前附加 -
。
额外的正则表达式 .replace(/[^A-Za-z]+/g, '')
将在插入连字符之前从第 2 组内容中删除所有 non-alpha 个字符。
这种方法确实会在任何给定长度的文本中找到并替换 OP 提到的模式,而不管该模式在该文本中的匹配频率如何。
它还使用非常简单的正则表达式 String.prototype.replace
。
正则表达式看起来确实是这样的……/\[\[([^|]+)\|([^\]]+)\]\]/g
……读起来是这样的……
\[\[
... 匹配(字面意思)两个左方括号 ...
([^|]+)
... 捕获每个字符序列 (link 文本) 不是管道 ...
\|
...然后匹配一个管道 ...
([^\]]+)
... 捕获每个字符序列 (非常 url) 不是右方括号 ...
\]\]
... 然后匹配两个右方括号。
/ ... /g
... 将正则表达式标记为全局 processed/applied 模式。
const sampleUrl = 'https://example.com/'
const sampleText = `Text [[Link A|ThisIsLinkA]] text. Text [[Link B|thisIsLinkB]] text.
Text [[Link C|This-Is-Link-C]] text.
Text [[Link D|ThisIsLinkD]] text. Text [[Link E|-this--Is--Link--E]] text.`;
function convertLinkMarkup(text, baseUrl) {
function ensureKebabCase(str) {
return str
.replace((/([A-Z])/g), '-') // - prefix any latin uppercase char with '-'.
.replace((/-+/g), '-') // - replace any '-' sequence with a single '-'.
.replace((/^-+/g), '') // - trim any leading '-' sequence.
.toLowerCase(); // - lower-case the result.
}
function createLinkMarkup(match, text, path) {
return `[${ text }](${ baseUrl }${ ensureKebabCase(path) })`;
}
const regXUrl = (/\[\[([^|]+)\|([^\]]+)\]\]/g);
return text.replace(regXUrl, createLinkMarkup);
}
console.log(
sampleText,
'\n\n... => ...\n\n',
convertLinkMarkup(sampleText, sampleUrl)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
我需要像这样转换:
[[Click here|ThisIsALink]]
至:
[Click here](https://example.com/this-is-a-link)
我可以通过使用此正则表达式 /\[\[(.*?)\|(.*?)\]\]/g
找到第一个 [[Click here|ThisIsALink]]
,我可以将其替换为 [Click here](https://example.com/ThisIsALink])
,但是我该如何处理最后一部分并将其转换为 this-is-a-link
?我已经尝试了一些事情,但我似乎找到了所有 PascalCased 事件,而不仅仅是在第一个找到的正则表达式模式中发生的事件。 (我正在将 .md 文件转换为 .pdf,所以它是一整页的内容,而不仅仅是这些链接)。
这是我目前所拥有的
var exampleUrl = "https://example.com/";
var urlOne = /\[\[(.*?)\|(.*?)\]\]/g;
data.replace(urlOne, "[](" + exampleUrl + ")"));
这导致:
[Click here](https://example.com/ThisIsALink)
您可以使用
const texts = ["Text [[Click here|ThisIsALink]] text...",
"Text [[Click here|This-Is-A-Link]] text..."];
const exampleUrl = "https://example.com/";
const urlOne = /\[\[((?:(?!\[\[).)*?)\|(.*?)]]/g;
for (var text of texts) {
console.log(
text.replace(urlOne, (_,x,y) =>
`[${x}](${exampleUrl}${y.replace(/[^A-Za-z]+/g, '')
.replace(/(?!^)[A-Z]/g, '-$&')
.toLowerCase()})`) );
}
正则表达式 #1 详细信息:
\[\[
-[[
字符串((?:(?!\[\[).)*?)
- 第 1 组:除换行符以外的任何字符,零次或多次,尽可能少,不开始[[
字符序列\|
- 一个|
字符(.*?)
- 第 2 组:除换行字符外的任何零个或多个字符,尽可能少]]
-]]
字符串。
第二个正则表达式、(?!^)[A-Z]
应用于第 2 组内容,并匹配任何不在字符串开头的大写 ASCII 字母。 -$&
替换只是在匹配之前附加 -
。
额外的正则表达式 .replace(/[^A-Za-z]+/g, '')
将在插入连字符之前从第 2 组内容中删除所有 non-alpha 个字符。
这种方法确实会在任何给定长度的文本中找到并替换 OP 提到的模式,而不管该模式在该文本中的匹配频率如何。
它还使用非常简单的正则表达式 String.prototype.replace
。
正则表达式看起来确实是这样的……/\[\[([^|]+)\|([^\]]+)\]\]/g
……读起来是这样的……
\[\[
... 匹配(字面意思)两个左方括号 ...([^|]+)
... 捕获每个字符序列 (link 文本) 不是管道 ...\|
...然后匹配一个管道 ...([^\]]+)
... 捕获每个字符序列 (非常 url) 不是右方括号 ...\]\]
... 然后匹配两个右方括号。/ ... /g
... 将正则表达式标记为全局 processed/applied 模式。
const sampleUrl = 'https://example.com/'
const sampleText = `Text [[Link A|ThisIsLinkA]] text. Text [[Link B|thisIsLinkB]] text.
Text [[Link C|This-Is-Link-C]] text.
Text [[Link D|ThisIsLinkD]] text. Text [[Link E|-this--Is--Link--E]] text.`;
function convertLinkMarkup(text, baseUrl) {
function ensureKebabCase(str) {
return str
.replace((/([A-Z])/g), '-') // - prefix any latin uppercase char with '-'.
.replace((/-+/g), '-') // - replace any '-' sequence with a single '-'.
.replace((/^-+/g), '') // - trim any leading '-' sequence.
.toLowerCase(); // - lower-case the result.
}
function createLinkMarkup(match, text, path) {
return `[${ text }](${ baseUrl }${ ensureKebabCase(path) })`;
}
const regXUrl = (/\[\[([^|]+)\|([^\]]+)\]\]/g);
return text.replace(regXUrl, createLinkMarkup);
}
console.log(
sampleText,
'\n\n... => ...\n\n',
convertLinkMarkup(sampleText, sampleUrl)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }