#javascript #regex #regex-group
#javascript #регулярное выражение #регулярное выражение-группа
Вопрос:
У меня есть строки, которые могут выглядеть так:
<!--Tag:Name-->
<!--Tag:Name param="abc"-->
<!--Tag:Name param="abc" param2="xyz"-->
Кроме того, у меня есть файл со многими из этих тегов, поэтому я хочу сначала найти все теги, а затем проанализировать каждый по одному
пример файла
<head>
<!--Tag:Test-->
<!--Tag:Test2 param="abc"-->
<!--Tag:Test3 param2="abc" param5="xyz"-->
</head>
Я ищу регулярное выражение для анализа такого рода скриптов и в соответствии получаю имя и атрибуты
Я пробовал что-то вроде
tempRegex = new RegExp(/<!--Tag:(.*?)s{1,}(.*?=".*?")-->/, 'i');
`<!--Tag:Test param="abc" param2="xyz"-->`.match(tempRegex);
Но он возвращает совпадающие группы:
0: "<!--Tag:Test param="abc" param2="xyz"-->"
1: "Test"
2: "param="abc" param2="xyz""
Чего я хочу добиться, так это
0: "<!--Tag:Test param="abc" param2="xyz"-->"
1: "Test"
2: param="abc"
3: param2="xyz"
Комментарии:
1. Вы указали, что он делает. Проблема не в этом.
2. Кроме того, есть ли причина, по которой это должно быть комментарием?
<template tag="Name" param="abc" param2="xyz"></template>
было бы намного проще обрабатывать с существующей собственной логикой
Ответ №1:
Вы хотите извлечь что-то вроде «ключ — значение»?
((w )[:=]"*(w )"*)
Это было бы:
Tag:Test
param="abc"
param2="xyz"
Комментарии:
1. Да, я хочу извлечь в массив, который выглядит как [Имя тега, первая пара, вторая пара и т. Д.]
2. Это приведет к сбою для чего-то вроде
<!--Tag:Name param="a:bc"-->
Ответ №2:
Это сделало бы это:
/Tag:[a-z] |[a-zd] ="[^"] "/gmi
https://regex101.com/r/6dVJXO/1
var s = `<!--Tag:Name param="abc" param2="xyz"-->`;
var r = /Tag:[a-z] |[a-zd] ="[^"] "/gmi;
console.log([...s.matchAll(r)]);
Комментарии:
1. выглядит красиво, но также соответствует
<Tag:Name param="abc" param2="xyz">
, кроме того, я бы предпочел не глобальное регулярное выражение, если это возможно, потому что сначала мне нужно получить все эти совпадающие теги из файла, а затем проанализировать каждый по одному2. @goq123 Я вижу, что вы обновили свой вопрос, чтобы выявить новые требования, поэтому первым шагом будет запуск
/<!--.[sS]*?-->/g
( regex101.com/r/vhl4Ln/1 ) для всей строки выполните цикл совпадений и запустите регулярное выражение, которое я указал в ответе, для каждого совпадения.3. @goq123 Кроме того, в вашем вопросе указано, что вы можете комментировать блоки, так что случилось
<Tag:Name param="abc" param2="xyz">
??4. у меня есть строгое правило, которое я сопоставляю только
<!--Tag:name-->
с параметрами или без них, меня интересует только эта форма подписи5. @goq123 Для дальнейшего использования сделайте свой вопрос как можно более полным. Вы можете легко объединить все, что я вам показал, во что-то, что работает для вас.
Ответ №3:
Вы можете ознакомиться с исходным кодом по адресу https://github.com/artdecocode/rexml это вроде как делает то, что вы хотите, но вам нужно знать название тегов в advanced, но вы можете изменить регулярное выражение.
/**
* Extract member elements from an XML string. Numbers and booleans will be parsed into their JS types.
* @param {string|!Array<string>} tag Which tag to extract, e.g., `div`. Can also pass an array of tags, in which case the name of the tag will also be returned.
* @param {string} string The XML string.
* @example
*
* const xml = `
* <html>
* <div id="1" class="test" contenteditable>
* Hello World
* </div>
* </html>
* `
* const [{ content, props }] = extractTag('div', xml)
* // content: Hello World
* // props: { id: 1, class: 'test', contenteditable: true }
*/
const extractTags = (tag, string) => {
const tags = Array.isArray(tag) ? tag : [tag]
const t = tags.join('|')
const end1 = /s*/>/
const end2 = />([sS] ?)?</1>/
const re = new RegExp(`<(${t})${simple.source}?(?:${end1.source}|${end2.source})`, 'g')
const matches = mismatch(re, string, ['t', 'a', 'v', 'v1', 'v2', 'c'])
const res = matches.map(({ 't': tagName, 'a': attributes = '', 'c': content = '' }) => {
const attrs = attributes.replace(//$/, '').trim()
const props = extractProps(attrs)
return { content, props, tag: tagName }
})
return res
}