Jump to content
  • 0

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


Great Rash
 Share

Question

Дано строка:

<span style="font-weight: bold;">bold</span> some text <span style="font-style: italic;">italic</span> some other text

Надо написать регулярку, которая заменит <span style="font-weight: bold;">bold</span> на <b>bold</b>.

Пишу такую регулярку:

str = str.replace(/<span.* style="font-weight: bold;">(.*)<\/span>/g, '<b>$1</b>');

Получаю на выходе вот такую строку:

<b>bold</span> some text <span style="font-style: italic;">italic</b> some other text

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

Link to comment
Share on other sites

21 answers to this question

Recommended Posts

  • 0

Лови дружище

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Удалить Спаны.</title>
<style type="text/css">
*{ margin: 0; padding: 0;}

</style>
</head>

<body>
<div id="wrap">
<span style="font-weight: bold;">bold</span> some text <span style="font-style: italic;">italic</span>
</div>
<script type="text/javascript">


var wrap = document.getElementById('wrap');


var re = /<span.*?>.+?<\/span>/g
var str = wrap.innerHTML.replace(re,'<b> bold </b>');
alert(str)




</script>
</body>
</html>

Link to comment
Share on other sites

  • 0
psywalker, ты гений! Я блин 3 часа уже доки мучаю... ну не даются мне эти регулярки хоть тресни... и как ты их так быстро схватываешь...

Ага, хрен там было, я просто этот пример когда-то сам три года решал. Оказалось, что всё дело в "Нежадности", а точнее в .*? - знак вопроса, который ставит Нежадность, и которая как раз и помогает решить этот пример :)

Link to comment
Share on other sites

  • 0
Я про эти жадности нежадности вообще невдупляю...

Да я тоже сначала не просекал, потом понял, в чём маза. Смотри, короче, например есть вот такой тег спан с атрибутами <span style="font-weight: bold;">Мир!!!</span>, в регулярках есть знак точка ".", который означает "Любые символы, кроме перевода строки". Соответственно если написать такую регулярку <span .*>, то регулярка отхватит кусок, аж до последнего закрывающего тега ">". В нашем случае выходит аж до сюда </span>. А нам нужно, чтобы регулярка тормазнула на <span style="font-weight: bold;"> и поэтому мы и ставим знак вопроса "?", который и означает "Нежадность", благодаря которой регулярка не идёт дальше первых закрывающихся кавычек > - <span style="font-weight: bold;"> :)

Слушай, а если эти теги буду вложенными как быть?

А покажи пример.

Link to comment
Share on other sites

  • 0

А как же она ищет закрывающий тег? Ведь по логике она должна тут остановиться .+??

А покажи пример.

Показываю, дано:

some text <span style="font-weight: bold;"><span style="font-style: italic;">bold italic</span></span> some text

Сейчас у меня на выходе:

some text <span style="font-style: italic; font-weight: bold;">bold italic</span> some text

Link to comment
Share on other sites

  • 0
А как же она ищет закрывающий тег? Ведь по логике она должна тут остановиться .+??

Ну смотри, ведь мы после знака вопроса ставим >, т.е. НЕжадность дойдёт только до первого симвова >

Показываю, дано:

some text <span style="font-weight: bold;"><span style="font-style: italic;">bold italic</span></span> some text

Сейчас у меня на выходе:

some text <span style="font-style: italic; font-weight: bold;">bold italic</span> some text

Только пока такую хрень придумал.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Удалить Спаны.</title>
<style type="text/css">
*{ margin: 0; padding: 0;}

</style>
</head>

<body>
<div id="wrap">
<span style="font-weight: bold;"><span style="font-style: italic;">bold italic</span></span> some text
</div>
<script type="text/javascript">


var wrap = document.getElementById('wrap');
var re = /<span.*?>(.+)<\/span>/g

var str = wrap.innerHTML.replace(re,'<b> $1 </b>');
var str = str.replace(re,'<b> $1 </b>');
alert(str)




</script>
</body>
</html>

Link to comment
Share on other sites

  • 0
Ну смотри, ведь мы после знака вопроса ставим >, т.е. НЕжадность дойдёт только до первого симвова >

Не понял, а как же закрывающий тег?

Нет этот код не пойдет... Дело в том, что на выходе мне необходимо получить:

some text <b><i>bold italic</i></b> some text

Фишка в том, что я пишу свой велосипед wysiwyg-редактор, а код разные браузеры генерируют разный. Вот я и хочу его перед отправкой на сервер приводить к общему знаменателю...

Link to comment
Share on other sites

  • 0
Ну смотри, ведь мы после знака вопроса ставим >, т.е. НЕжадность дойдёт только до первого симвова >

Не понял, а как же закрывающий тег?

Нежадность идёт ДО первой закрывающей кавычки > например. А если тебе нужен самый последний закрывающий тег, то просто убери знак вопроса из середины между спанов, как тут /<span.*?>(.+)<\/span>/

А вот так не пойдёт?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Удалить Спаны.</title>
<style type="text/css">
*{ margin: 0; padding: 0;}

</style>
</head>

<body>
<div id="wrap">
<span style="font-weight: bold;"><span style="font-style: italic;">bold italic</span></span> some text
</div>
<script type="text/javascript">


var wrap = document.getElementById('wrap');
var re = /<span.*?>(.+)<\/span>/g

var str = wrap.innerHTML.replace(re,'<b> $1 </b>');
var str = str.replace(re,'<i> Bold italic </i>');
alert(str)




</script>
</body>
</html>

Link to comment
Share on other sites

  • 0

Дружище, вот кстати примеры про жадность хорошие http://javascript.ru/tutorial/regexp-specials#zhadnost

Нет не пойдет. Мне надо знать какой из них болд а какой италик. Они же могут быть вложены наоборот.

А я просто не понял задачу.

Что у нас есть вначале, какой код HTML? И какую регулярку нужно написать, что нужно получить на выходе?

Link to comment
Share on other sites

  • 0
А я просто не понял задачу.

Что у нас есть вначале, какой код HTML? И какую регулярку нужно написать, что нужно получить на выходе?

Итак, рассказываю по порядку. Я делаю wysiwyg - т.е. редактор типа ворда, юзер пишет что-то в <iframe>, а на выходе получается готовый HTML-код, который потом можно вставить на страницу в нужном месте. Как работает мой wysiwyg:

1) Вместо <textarea> создается <iframe> с неким пустым документом.

2) Для документа (document) этого <iframe> задается режим редактирования (document.designMode = 'On';)

3) Это позволяет использовать метод execCommand с различными параметрами для выделения текста жирным, курсивом, подчеркнутым текстом (и т.п., команд много)

4) Когда используется команда (execCommand) в документе автоматически создается нужная нода, но проблема в том, что API разных браузеров по разному создает эти ноды. Вот пример для жирного текста:

IE (6/7/8) - <STRONG>текст</STRONG>

Opera - <strong>текст</strong>

FireFox - <span style="font-weight: bold;">текст</span>

Chrome - <b>текст</b>

Safari - <b>текст</b>

5) Перед отправкой у меня отрабатывает функция очистки кода, которая должна приводить код в разных браузерах к некоему общему коду.

6) Я решил, что путь Хрома и Сафари самый правильный, поэтому при помощи регулярок я заменяю не нужные теги на нужные.

7) Заменить <STRONG> и <strong> на <b> не проблема, а вот с заменой <span> я и мучаюсь.

8) Проблема в том, что Мозилла создает спаны для всего (для курсива, жирного текста, подчеркнутого и т.п.) поэтому они могут быть по всякому вложены друг в друга.

Надеюсь теперь понятно, что у меня не получается и почему?

Link to comment
Share on other sites

  • 0

Да, но почему-бы не воспользоваться моим решением вверху. Сначала <span style="font-weight: bold;"> <span style="font-weight: bold;">текст</span></span> превратиться в <b ><span style="font-weight: bold;"></span> текст</b>. А после уже и просто в <b>текст</b>, как тебе и нужно.

Link to comment
Share on other sites

  • 0

<span style="font-weight: bold;"><span style="font-style: italic;">bold italic</span></span> some text

превращается в

<span style="font-weight: bold; font-style: italic;">bold italic</span> some text

регулярка, которую я юзаю

str = str.replace(/<span.* style="font-weight: bold;"?>(.+)<\/span>/g, '<b>$1</b>');
str = str.replace(/<span.* style="font-style: italic;"?>(.+)<\/span>/g, '<i>$1</i>');

Что я делаю не так?

О! Придумал... у меня ж ноды формируются. Попробую менять HTML на уровне DOM, а не на уровне текста! А то я замучился уже с этими регулярками...

Link to comment
Share on other sites

  • 0
<span style="font-weight: bold;"><span style="font-style: italic;">bold italic</span></span> some text

превращается в

<span style="font-weight: bold; font-style: italic;">bold italic</span> some text

регулярка, которую я юзаю

str = str.replace(/<span.* style="font-weight: bold;"?>(.+)<\/span>/g, '<b>$1</b>');
str = str.replace(/<span.* style="font-style: italic;"?>(.+)<\/span>/g, '<i>$1</i>');

Что я делаю не так?

Так не пойдёт? :)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Удалить Спаны.</title>
<style type="text/css">
*{ margin: 0; padding: 0;}

</style>
</head>

<body>
<div id="wrap">
<span style="font-weight: bold;"><span style="font-style: italic;">bold italic</span></span> some text[/i]
</div>
<script type="text/javascript">


var wrap = document.getElementById('wrap');
var re = /<span.*italic.*?>(.+)<\/span>/g

var str = wrap.innerHTML.replace(re,'<b> $1 </b>');
var str = str.replace(/<\/span>/,'');
alert(str)




</script>
</body>
</html>

О! Придумал... у меня ж ноды формируются. Попробую менять HTML на уровне DOM, а не на уровне текста! А то я замучился уже с этими регулярками...

Отлично, потом покажи результат плиз :)

Link to comment
Share on other sites

  • 0
Отлично, потом покажи результат плиз

Весь код? Я вообще потом планировал еще один туториал написать по созданию wysiwyg, а то таких уроков в рунете почти нет...

Или тебя именно этот кусок интересует? Тогда могу сразу показать.

Link to comment
Share on other sites

  • 0

function clean(doc) {
// clean Bold
var strongs = doc.body.getElementsByTagName('strong'); // IE, Opera
var spansBold = doc.body.getElementsByTagName('span'); // FireFox (Gecko)

if (strongs.length > 0) {
for (var s = strongs.length - 1; s >= 0; s--) {
var bold = doc.createElement('b');
bold.innerHTML = strongs[s].innerHTML;
strongs[s].parentNode.insertBefore(bold, strongs[s]);
strongs[s].parentNode.removeChild(strongs[s]);
}
}

if (spansBold.length > 0) {
for (var sb = spansBold.length - 1; sb >= 0; sb--) {
alert(spansBold[sb].style.fontWeight);
if (spansBold[sb].style.fontWeight == 'bold') {
var bold = doc.createElement('b');
bold.innerHTML = spansBold[sb].innerHTML;
spansBold[sb].parentNode.insertBefore(bold, spansBold[sb]);
spansBold[sb].parentNode.removeChild(spansBold[sb]);
}
}
}

// clean Italic
var italics = doc.body.getElementsByTagName('em'); // IE, Opera
var spansItalic = doc.body.getElementsByTagName('span'); // FireFox (Gecko)

if (italics.length > 0) {
for (var i = italics.length - 1; i >= 0; i--) {
var italic = doc.createElement('i');
italic.innerHTML = italics[i].innerHTML;
italics[i].parentNode.insertBefore(italic, italics[i]);
italics[i].parentNode.removeChild(italics[i]);
}
}

if (spansItalic.length > 0) {
for (var si = spansItalic.length - 1; si >= 0; si--) {
if (spansItalic[si].style.fontStyle == 'italic') {
var italic = doc.createElement('i');
italic.innerHTML = spansItalic[si].innerHTML;
spansItalic[si].parentNode.insertBefore(italic, spansItalic[si]);
spansItalic[si].parentNode.removeChild(spansItalic[si]);
}
}
}

return doc;
}

Монстр получается... может и правда лучше регулярками? Народ, подскажите что лучше? s0rr0w?

Link to comment
Share on other sites

  • 0

Чёт я тут почитал и не понял решилась проблема из первого поста или нет. Но вот мой вариант решения

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<body>
<script type="text/javascript">
function test(str)
{
return str.replace(/<span[^>]+style="font-weight: bold;">([^(<\/span>)]*)<\/span>/g, '<b>$1</b>');
}
document.write(test('<span style="font-weight: bold;">bold</span> some text <span style="font-style: italic;">italic</span> some other text <span style="font-weight: bold;">bold1!!! OLOLO!!!</span>. It works!'));
</script>
</body>
</html>

Link to comment
Share on other sites

  • 0

А если спаны будут вложены друг в друга, функция сработает?

<span style="font-weight: bold;"><span style="font-style: italic;">bold italic</span></span> some text

или наоборот

<span style="font-style: italic;"><span style="font-weight: bold;">bold italic</span></span> some text

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy