Найти подстроки, которые начинаются и заканчиваются одним и тем же заглавным символом - PullRequest
3 голосов
/ 11 мая 2019

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

Цель состоит в том, чтобы выбрать подстроки, которые соответствуют следующим параметрам:

Подстрока начинается и заканчивается тем же символом в верхнем регистре, и мне нужно игнорировать любые случаи символов в верхнем регистре с номером 0 перед ними.

Например, ZAp0ZuZAuX0AZA будет содержать совпадения ZAp0ZuZ и AuX0AZA

Я возился с этим несколько часов и, честно говоря, даже близко не подошел ...

Я пробовал некоторые вещи, такие как приведенный ниже код, но он будет выбирать все от первого верхнего регистра до последнего верхнего регистра. Я также

[A-Z]{1}[[:alnum:]]*[A-Z]{1} <--- this selects the whole string
[A-Z]{1}[[:alnum:]][A-Z]{1} <--- this gives me strings like ZuZ, AuX

Действительно ценю любую помощь, я в полном восторге от этого.

Ответы [ 3 ]

1 голос
/ 11 мая 2019

Это может сработать

(?<!0)([A-Z]).*?(?<!0)\1

https://regex101.com/r/nES9FP/1

Объяснил

 (?<! 0 )      # Ignore Upper case with zero in front of it
 ( [A-Z] )     # (1), This Upper case is to be found down stream
 .*?           # Lazy, any character
 (?<! 0 )      # Ignore Upper case with zero in front of it
 \1            # Backref to what is in group (1)
0 голосов
/ 11 мая 2019

Возможно, не самая лучшая идея делать это с регулярными выражениями, поскольку вы просто можете разделить их. Однако, если вы хотите / хотите сделать это, это выражение может дать вам представление о том, с какими проблемами вы можете столкнуться, когда ваш список символов расширяется:

(?=.[A-Z])([A-Z])(.*?)\1

Я добавил (?=.[A-Z]), который должен содержать одну заглавную букву. Вы можете удалить это, и это будет работать. Однако вы можете добавить такие границы в свои выражения для безопасности.

enter image description here

enter image description here

JavaScript-тест

const regex = /([A-Z])(.*?)\1/gm;
const str = `ZAp0ZuZAuX0AZA
ZApxxZuZAuXxafaAZA
ZApxaf09xZuZAuX090xafaAZA
abcZApxaf09xZuZAuX090xafaAZA`;
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}`);
    });
}

Python Test

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"([A-Z])(.*?)\1"

test_str = ("ZAp0ZuZAuX0AZA\n"
    "ZApxxZuZAuXxafaAZA\n"
    "ZApxaf09xZuZAuX090xafaAZA\n"
    "abcZApxaf09xZuZAuX090xafaAZA")

matches = re.finditer(regex, test_str, re.MULTILINE)

for matchNum, match in enumerate(matches, start=1):

    print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))

    for groupNum in range(0, len(match.groups())):
        groupNum = groupNum + 1

        print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.
0 голосов
/ 11 мая 2019

Вы можете использовать

(?<!0)([A-Z]).*?(?<!0)\1

См. Демоверсию regex .

Детали

  • (?<!0)([A-Z]) - Группа 1: заглавная буква ASCII без нуля
  • .*? - любой символ, кроме символа перевода строки, как можно меньше
  • (?<!0)\1 - та же буква, что и в группе 1, которой непосредственно не предшествует 0.

См. Демоверсию Python :

import re
s="ZAp0ZuZAuX0AZA"
for m in re.finditer(r'(?<!0)([A-Z]).*?(?<!0)\1', s):
    print(m.group()) # => ['ZAp0ZuZ', 'AuX0AZA']
...