2012-06-03 2 views
9

Мне нужна помощь в написании функции регулярного выражения, которая преобразует строку HTML в действительное имя тега XML. Пример: Он принимает строку и выполняет следующие функции:Regex - преобразовать HTML в действительный тег XML

  • Если алфавит или подчеркивание происходит в строке, он держит его
  • При возникновении какой-либо другой символ, он удаляется из строки вывода.
  • Если какой-либо другой символ встречается между словами или буквами, он заменяется символом подчёркивания.
Ex: 
Input: Date Created 
Ouput: Date_Created 

Input: Date<br/>Created 
Output: Date_Created 

Input: Date\nCreated 
Output: Date_Created 

Input: Date 1 2 3 Created 
Output: Date_Created 

В основном функция регулярного выражения должна преобразовать строку HTML для действительного тега XML.

+3

Ваш вопрос говорит: «Я хочу писать», но читается как список требований и ждет кого-то отказаться от желаемых магические коды регулярных выражений. Неясно, что вы считаете XML-тегами в любом случае, в выходных примерах нет ни одного. – mario

+0

@JackManey: У этого теперь более 4000 upvotes ..? Sheesh. – mpen

+1

Что не так, если ситуация возникает только один раз в голубой луне, и это просто добавить «быстрый и грязный патч» к вашему тестовому коду в вихре! И ИСПОЛЬЗОВАТЬ REGEX INSTEAD OF DOM ... – Cylian

ответ

5

Немного регулярных выражений и немного стандартных функций:

function mystrip($s) 
{ 
     // add spaces around angle brackets to separate tag-like parts 
     // e.g. "<br />" becomes " <br /> " 
     // then let strip_tags take care of removing html tags 
     $s = strip_tags(str_replace(array('<', '>'), array(' <', '> '), $s)); 

     // any sequence of characters that are not alphabet or underscore 
     // gets replaced by a single underscore 
     return preg_replace('/[^a-z_]+/i', '_', $s); 
} 
2

Попробуйте

$result = preg_replace('/([\d\s]|<[^<>]+>)/', '_', $subject); 

Объяснение

" 
(    # Match the regular expression below and capture its match into backreference number 1 
        # Match either the regular expression below (attempting the next alternative only if this one fails) 
     [\d\s]   # Match a single character present in the list below 
         # A single digit 0..9 
         # A whitespace character (spaces, tabs, and line breaks) 
    |    # Or match regular expression number 2 below (the entire group fails if this one fails to match) 
     <    # Match the character “<” literally 
     [^<>]   # Match a single character NOT present in the list “<>” 
     +    # Between one and unlimited times, as many times as possible, giving back as needed (greedy) 
     >    # Match the character “>” literally 
) 
" 
2

Должно быть в состоянии использовать:

$text = preg_replace('/(?<=[a-zA-Z])[^a-zA-Z_]+(?=[a-zA-Z])/', '_', $text); 

Итак, есть lookarounds, чтобы увидеть, если есть альфа-символ перед и fter и заменяет между собой не-альфа/не-подчеркивание.

1

Я считаю, что следующее должно работать.

preg_replace('/[^A-Za-z_]+(.*)?([^A-Za-z_]+)?/', '_', $string); 

Первая часть регулярного выражения [^A-Za-z_]+ соответствуют один или несколько символам, что не является алфавитным или подчеркиванием. Конечная часть регулярного выражения такая же, за исключением необязательной. Это значит, что средняя часть, (.*)?, которая также является необязательной, позволяет поймать любые символы (даже в алфавитном порядке и подчеркивания) между двумя черными листами.

Смежные вопросы