регулярное выражение для сопоставления слова, разделенного символами и заключенного в теги xml - PullRequest
2 голосов
/ 27 декабря 2011

Я пытался построить регулярное выражение, чтобы сделать следующее:

Найдите слово «алфавит», заключенное в теги xml, поиск будет соответствовать следующему:

<hw>Al"pha*bet</hw>
<hw>Al"pha*be`t</hw>        
<hw>alphabet</hw>    
<hw>al*pha*bet</hw>        
<hw>al"pha"b"et</hw>

Слово может быть разделено 3 специальными символами: "*`, поиск должен иметь регистронезависимый. Не могли бы вы помочь мне, построив регулярное выражение, которое бы специально искать слово алфавит с любым из или без специальные символы, упомянутые выше.

Ответы [ 3 ]

2 голосов
/ 27 декабря 2011

Это будет работать с оговоркой о том, что регулярное выражение не следует использовать для анализа xml / html и т. Д.

Всегда проще захватывать простые выборки, а затем обрабатывать их в обратном вызове.
В этом случае захват ([алфавит * *,] +), затем удаление ненужных символов и сравнение.

Пример Perl, концепция Perl / PHP / C # и т. Д. Та же...

$sample = '
  <hw>Al"pha*bet</hw>
  <hw>Al"pha*be`t</hw>        
  <hw>alphabet</hw>    
  <hw>al*pha*bet</hw>        
  <hw>al"pha"b"et</hw>
';

$specialword = 'alphabet';
$uc_specialword = uc( $specialword );

while ($sample =~ m{<([A-Za-z_:][\w:.-]*)(?:\s+(?:".*?"|\'.*?\'|[^>]*?)+)?\s*(?<!/)>([$specialword"*`,]+)</\1\s*>}isg)
{
    ($matchstr, $checkstr) = ($&, $2);
    $checkstr =~ s/["*`,]//g;
    if (uc($checkstr) eq $uc_specialword) {
       print "Found '$checkstr' in '$matchstr'\n";
    } 
}

Расширенное регулярное выражение:

m{   # Regex delim
<                         # Open tag
  ([A-Za-z_:][\w:.-]*)                  # Capture 1, the tag name
  (?:\s+(?:".*?"|\'.*?\'|[^>]*?)+)?\s*  # optional attr/val pairs
  (?<!/)
>
([alphabet"*`,]+)        # Capture 2, class of special characters allowed, 'alphabet' plus "*`,
</\1\s*>                 # Close tag, backref to tag name (group 1)

}xisg  # Regex delim. Options: expanded, case insensitive, single line, global

Вывод:

Found 'Alphabet' in '<hw>Al"pha*bet</hw>'
Found 'Alphabet' in '<hw>Al"pha*be`t</hw>'
Found 'alphabet' in '<hw>alphabet</hw>'
Found 'alphabet' in '<hw>al*pha*bet</hw>'
Found 'alphabet' in '<hw>al"pha"b"et</hw>'

Пример PHP

Использованиеpreg_match() можно найти здесь http://www.ideone.com/8EBpx

<?php

  $sample = '
    <hw>Al"pha*bet</hw>
    <hw>Al"pha*be`t</hw>        
    <hw>alphabet</hw>    
    <hw>al*pha*bet</hw>        
    <hw>al"pha"b"et</hw>
  ';

  $specialword = 'alphabet';
  $uc_specialword = strtoupper( $specialword );
  $regex = '~<([A-Za-z_:][\w:.-]*)(?:\s+(?:".*?"|\'.*?\'|[^>]*?)+)?\s*(?<!/)>([' . $specialword. '"*`,]+)</\1\s*>~xis';
  $pos = 0;

  while ( preg_match($regex, $sample, $matches, PREG_OFFSET_CAPTURE, $pos) )
  {
     $matchstr = $matches[0][0];
     $checkstr = $matches[2][0];

     $checkstr = preg_replace( '/[" * `,]/', "", $checkstr);
     if ( strtoupper( $checkstr ) == $uc_specialword )
         print "Found '$checkstr' in '$matchstr'\n";

     $pos = $matches[0][1] + strlen( $matchstr );
  }

?>

Использование preg_match_all() можно найти здесь http://www.ideone.com/C6HeT

<?php

  $sample = '
    <hw>Al"pha*bet</hw>
    <hw>Al"pha*be`t</hw>        
    <hw>alphabet</hw>    
    <hw>al*pha*bet</hw>        
    <hw>al"pha"b"et</hw>
  ';

  $specialword = 'alphabet';
  $uc_specialword = strtoupper( $specialword );
  $regex = '~<([A-Za-z_:][\w:.-]*)(?:\s+(?:".*?"|\'.*?\'|[^>]*?)+)?\s*(?<!/)>([' . $specialword. '"*`,]+)</\1\s*>~xis';

  preg_match_all($regex, $sample, $matches, PREG_SET_ORDER);

  foreach ($matches as $match)
  {
     $matchstr = $match[0];
     $checkstr = $match[2];

     $checkstr = preg_replace( '/[" * `,]/', "", $checkstr);
     if ( strtoupper( $checkstr ) == $uc_specialword )
         print "Found '$checkstr' in '$matchstr'\n";
  }

?>
1 голос
/ 27 декабря 2011

Вы можете попробовать это

a([`"\*])*l([`"\*])*p([`"\*])*h([`"\*])*a([`"\*])*b([`"\*])*e([`"\*])*t

или это

>\s*a([`"\*])*l([`"\*])*p([`"\*])*h([`"\*])*a([`"\*])*b([`"\*])*e([`"\*])*t\s*<

Редактировать

Извините, забыл убежать *

0 голосов
/ 27 декабря 2011

Один, который я получил, работает для перечисленных вами случаев:

/<[a-zA-Z]+>al"*\**pha\**\"*b\"*e`*t<\/[a-zA-Z]+>/i

Проверьте http://www.rubular.com/. У него есть живой тест регулярных выражений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...