Подтвердить что ты не робот

Соответствие повторяющихся подстрок в регулярном выражении

Возможно ли соответствие регулярного выражения на основе других частей одного и того же регулярного выражения?

Например, как бы я совпадал с строками, которые начинаются и заканчиваются на одну и ту же последовательность из 3 символов, независимо от того, что символы?

Матчи:

abcabc
xyz abc xyz

Не соответствует:

abc123

Undefined: (Может совпадать или нет, в зависимости от того, что проще)

ababa
a

В идеале, я бы хотел что-то в аромате regex perl. Если это не возможно, мне было бы интересно узнать, есть ли какие-либо вкусы, которые могут это сделать.

4b9b3361

Ответ 1

Используйте группы захвата и обратные ссылки.

/^(.{3}).*\1$/

\1 ссылается на все, что соответствует содержимому первой группы захвата (содержимое ()). Регулярные выражения в большинстве языков позволяют что-то вроде этого.

Ответ 2

Вам нужно обратные ссылки. Идея состоит в том, чтобы использовать группу захвата для первого бита, а затем ссылаться на нее, когда вы пытаетесь сопоставить последний бит. Здесь приведен пример сопоставления пары начальных и конечных тегов HTML (из ссылки, приведенной ранее):

<([A-Z][A-Z0-9]*)\b[^>]*>.*?</\1>

Это регулярное выражение содержит только одну пару круглых скобок, которые фиксируют строку, сопоставляемую [A-Z][A-Z0-9]*, в первую обратную ссылку. Эта обратная ссылка используется повторно с помощью \1 (обратная косая черта). /, прежде чем это просто косая черта в закрывающемся теге HTML, который мы пытаемся сопоставить.

Применение этого к вашему делу:

/^(.{3}).*\1$/

(Да, это регулярное выражение, которое написал Брайан Карпер. Просто не так много способов сделать это.)

Подробное объяснение ради потомства (пожалуйста, не оскорбляйтесь, если оно находится ниже вас):

  • ^ соответствует началу строки.
  • (.{3}) захватывает три символа любого типа и сохраняет их в группе для последующей ссылки.
  • .* подходит как можно дольше. (Тебе все равно, что находится в середине линии.)
  • \1 соответствует группе, которая была записана на шаге 2.
  • $ соответствует концу строки.

Ответ 3

Для тех же символов в начале и конце:

/^(.{3}).*\1$/

Это backreference.

Ответ 4

Это работает:

my $test = 'abcabc';
print $test =~ m/^([a-z]{3}).*(\1)$/;

Для соответствия началу и концу вы должны добавить привязки ^ и $.