Лексемы в регулярных выражениях

Введение

Круглые скобки, используемые в регулярном выражении не только, собирают в группу элементы того выражения, но также и называют любые соответствия найденными для той группы как лексемы. Можно использовать лексемы, чтобы совпадать с другими частями того же текста. Одно преимущество использования лексем состоит в том, что они помнят то, с чем они совпадали, таким образом, можно вспомнить, и повторное использование совпадало с текстом в процессе поиска или заменяющий.

Каждой лексеме в выражении присваивают номер, запускающийся от 1, идя слева направо. Чтобы сделать ссылку на лексему позже в выражении, обратитесь к нему с помощью наклонной черты влево, сопровождаемой маркерным номером. Например, при ссылке на лексему, сгенерированную третьим набором круглых скобок в выражении, используйте \3.

Как простой пример, если вы хотели искать идентичные последовательные буквы в символьном массиве, вы могли бы получить первую букву как лексему и затем искать соответствующий символ сразу впоследствии. В выражении, показанном ниже, фраза (\S) создает лексему каждый раз, когда regexp совпадает с любым непробельным символом в символьном массиве. Вторая часть выражения, '\1', ищет второй экземпляр того же символа сразу после первого:

poe = ['While I nodded, nearly napping, ' ...
       'suddenly there came a tapping,'];

[mat,tok,ext] = regexp(poe, '(\S)\1', 'match', ...
               'tokens', 'tokenExtents');
mat
mat = 
    'dd'    'pp'    'dd'    'pp'

Лексемы, возвращенные в массиве ячеек tok:

'd', 'p', 'd', 'p'

Запуск и конечные индексы для каждой лексемы в poe:

11 11,  26 26,  35 35,  57 57

Для другого примера получите пары соответствия с HTML-тэгами (e. g., <a> и </a>) и текст между ними. Выражение, используемое для этого примера,

expr = '<(\w+).*?>.*?</\1>';

Первая часть выражения, '<(\w+)', совпадает с открывающей угловой скобкой (<), сопровождаемый одним или несколькими алфавитные, числовые, или символы подчеркивания. Круглые скобки включения получают маркерные символы после открывающей угловой скобки.

Вторая часть выражения, '.*?>.*?', совпадает с остатком от этого HTML-тэга (символы до >) и любые символы, которые могут предшествовать следующей открывающей угловой скобке.

Последняя часть, '</\1>', совпадает со всеми символами в конечном HTML-тэге. Этот тег состоит из последовательности </tag>, где tag является любыми символами, были получены как лексема.

hstr = '<!comment><a name="752507"></a><b>Default</b><br>';
expr = '<(\w+).*?>.*?</\1>';

[mat,tok] = regexp(hstr, expr, 'match', 'tokens');
mat{:}
ans =
    <a name="752507"></a>
ans =
    <b>Default</b>
tok{:}
ans = 
    'a'
ans = 
    'b'

Несколько лексем

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

andy ted bob jim andrew andy ted mark

Вы принимаете решение искать вышеупомянутый текст со следующим поисковым шаблоном:

and(y|rew)|(t)e(d)

Этот шаблон имеет три вводных выражения, которые генерируют лексемы. Когда вы наконец выполняете поиск, следующие лексемы сгенерированы для каждого соответствия.

Соответствие

Лексема 1

Лексема 2

andy

y

 

ted

t

d

andrew

rew

 

andy

y

 

ted

t

d

Только круглые скобки высшего уровня используются. Например, если поисковый шаблон, and(y|rew) находит текст andrew, лексема 1, присвоен значение rew. Однако, если поисковый шаблон, (and(y|rew)) используется, лексема 1, присвоен значение andrew.

Несопоставленные лексемы

Для тех лексем, заданных в регулярном выражении, которые не имеют никакого соответствия в оцениваемом тексте, regexp и regexpi возвращают пустой символьный вектор ('') как маркерный вывод и степень, которая отмечает положение в строке, где лексема ожидалась.

Пример, показанный здесь, выполняет regexp на векторе символа, задающем путь, возвращенный в функцию MATLAB® tempdir. Регулярное выражение expr включает шесть маркерных спецификаторов, один для каждой части пути. Третий [a-z]+ спецификатора не имеет никакого соответствия в векторе символа, потому что эта часть пути, Profiles, начинается с прописной буквы:

chr = tempdir
chr =
   C:\WINNT\Profiles\bpascal\LOCALS~1\Temp\
expr = ['([A-Z]:)\\(WINNT)\\([a-z]+)?.*\\' ...
        '([a-z]+)\\([A-Z]+~\d)\\(Temp)\\'];

[tok, ext] = regexp(chr, expr, 'tokens', 'tokenExtents');

Когда лексема не найдена в тексте, regexp возвращает пустой символьный вектор ('') как лексема и числовой массив с маркерной степенью. Первое количество степени является индексом строк, который отмечает, где лексема ожидалась, и второе количество степени равно меньше, чем первое.

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

tok{:}
ans = 
    'C:'    'WINNT'     ''    'bpascal'    'LOCALS~1'    'Temp'

Третьей маркерной степени, возвращенной в переменном ext, установили начальное значение индекса на 10, который является, где не соответствующий семестр, Profiles, начинается в пути. Конечный индекс степени установлен в меньше, чем начальное значение индекса, или 9:

ext{:}
ans =
     1     2
     4     8
    10     9
    19    25
    27    34
    36    39

Лексемы в Замещаемом тексте

При использовании лексем в тексте замены сошлитесь на них использующий $1, $2, и т.д. вместо \1, \2, и т.д. Этот пример получает две лексемы и инвертирует их порядок. Первым, $1, является 'Norma Jean', и вторым, $2, является 'Baker'. Обратите внимание на то, что regexprep возвращает измененный текст, не вектор начальных значений индекса.

regexprep('Norma Jean Baker', '(\w+\s\w+)\s(\w+)', '$2, $1')
ans =
    Baker, Norma Jean

Названное получение

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

При ссылке на именованную лексему в рамках выражения используйте синтаксис \k<name> вместо числового \1, \2, и т.д.:

poe = ['While I nodded, nearly napping, ' ...
       'suddenly there came a tapping,'];

regexp(poe, '(?<anychar>.)\k<anychar>', 'match')
ans = 
    'dd'    'pp'    'dd'    'pp'

Названные лексемы могут также быть полезными в маркировке вывода от функций регулярного выражения MATLAB. Это особенно верно, когда вы обрабатываете много частей текста.

Например, проанализируйте различные части уличных адресов от нескольких векторов символов. Краткое название присвоено каждой лексеме в выражении:

chr1 = '134 Main Street, Boulder, CO, 14923';
chr2 = '26 Walnut Road, Topeka, KA, 25384';
chr3 = '847 Industrial Drive, Elizabeth, NJ, 73548';

p1 = '(?<adrs>\d+\s\S+\s(Road|Street|Avenue|Drive))';
p2 = '(?<city>[A-Z][a-z]+)';
p3 = '(?<state>[A-Z]{2})';
p4 = '(?<zip>\d{5})';

expr = [p1 ', ' p2 ', ' p3 ', ' p4];

Как следующие результаты демонстрируют, можно сделать вывод легче работать с при помощи именованных лексем:

loc1 = regexp(chr1, expr, 'names')
loc1 = 
     adrs: '134 Main Street'
     city: 'Boulder'
    state: 'CO'
      zip: '14923'
loc2 = regexp(chr2, expr, 'names')
loc2 = 
     adrs: '26 Walnut Road'
     city: 'Topeka'
    state: 'KA'
      zip: '25384'
loc3 = regexp(chr3, expr, 'names')
loc3 = 
     adrs: '847 Industrial Drive'
     city: 'Elizabeth'
    state: 'NJ'
      zip: '73548'

Смотрите также

| |

Похожие темы

Была ли эта тема полезной?