RegEx для сопоставления всего, кроме повторяющегося символа в начале и в конце - PullRequest
2 голосов
/ 11 мая 2019

У меня есть строковый шаблон, и примеры приведены ниже.

AA4grgrsragrga4334grAA

AAA4323425AAA

AAAAAA%%%AAAAAA

Ведущие буквы "А" и трейлинг Как всегда появляются в паре.

Я пробовал:

A+.+A+

Не знаю, как соединить ведущие As и трейлинг As в REGEX.

Ответы [ 3 ]

2 голосов
/ 11 мая 2019

Захватите начальную букву As в группе, затем несколько раз сопоставьте любые символы, за которыми следует не A, затем снова сделайте обратную ссылку на первую группу, а затем на конец строки:

^(A+).*[^A]\1$

https://regex101.com/r/81ge2k/2

Если A появится только в начале и в конце строки, вы можете использовать вместо этого отрицательный набор символов:

^(A+)[^A]*\1$

Обязательно используйте якоря начала строки и конца строки, если входная строка должна занимать всю строку, в противном случае шаблон может совпадать с A s.

0 голосов
/ 11 мая 2019

Это выражение имеет простую группу захвата между A+, которая пролистывает все не-A символы между слева направо:

A+([^A]*)A+

enter image description here


Если вы хотите захватить A+, вы можете просто обернуть их двумя группами захвата (), аналогично этому выражению :

(A+)([^A]*)(A+)

enter image description here


Если вы не хотите сопоставлять символ A, вы можете просто удалить их из выражения :

[^A]*

Однако это не будет совпадать, если между ними будет A, и его необходимо изменить.


Описательный график RegEx

Этот график отображает выражение, и, если хотите, вы можете проверить другие выражения в этой ссылке :

enter image description here

JavaScript тест

const regex = /(A+)([^A]*)(A+)/gm;
const str = `AA4grgrsragrga4334grAA
AAA4323425AAA
AAAAAA%%%AAAAAA`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Базовый тест производительности для (A +) ([^ A] *) (A +)

Этот фрагмент JavaScript возвращает время выполнения цикла for в миллион раз для повышения производительности.

const repeat = 1000000;
const start = Date.now();

for (var i = repeat; i >= 0; i--) {
	const string = 'AAAAAAAAAanyThingElse4grgrsragrga4334grAAAA';
	const regex = /(A+)([^A]*)(A+)/gm;
	var match = string.replace(regex, "\nGroup #1: $1\nGroup #2: $2\nGroup #3: $3\n");
}

const end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match ??? ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ? ");

Базовый тест производительности для A + ([^ A] *) A +

const repeat = 1000000;
const start = Date.now();

for (var i = repeat; i >= 0; i--) {
	const string = 'AAAAAAAAAanyThingElse4grgrsragrga4334grAAAA';
	const regex = /A+([^A]*)A+/gm;
	var match = string.replace(regex, "Group #1: $1");
}

const end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match ??? ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ? ");
0 голосов
/ 11 мая 2019

Если вы хотите сопоставить парные буквы A в начале и в конце для таких строк, как AA или AAAAAA, а также AAteAstAA, вы можете использовать чередование:

^(A+)(?:[^A].*[^A]|[^A])?\1$

О шаблоне

  • ^ Начало строки
  • (A+) Захват в первой группе совпадений 1+ A
  • (?: Группа без захвата
    • [^A].*[^A] Совпадениене A, 0+ раз любой символ кроме новой строки, затем снова не A
    • | или
    • [^A] Совпадение не A
  • )? Закрыть группу без захвата и сделать ее необязательной
  • \1 Обратная ссылка на группу 1
  • $ Конец строки

Regex demo

Если AAA также может совпадать, вы можете использовать

^(A+)(?:[^A].*[^A]|.)?\1$

Regex demo

...