JavaScript RegEx для соответствия пунктуации НЕ является частью любых HTML-тегов

Хорошо, я знаю много споров с совпадением и анализом HTML в RegEx, но мне было интересно, не могу ли я помочь. Случай и точка.

Мне нужно сопоставить любые знаки пунктуации, например . , " ', но я не хочу разрушать какой-либо HTML, поэтому в идеале это должно происходить между > и <. По существу мой запрос не столько о разбор HTML, как бы избежать его.

Я попытаюсь заменить wrap каждый экземпляр на <span></span>, но, не имея абсолютно никакого опыта в RegEx, я не уверен, что смогу это сделать.

Я определил набор символов [\.\,\'\"\?\!], но я не уверен, как сопоставлять наборы символов, которые встречаются только между определенными символами. Может ли кто-нибудь помочь?

Ответ 1

Для начала, здесь функция dom-parser для X-браузера:

var parseXML = (function(w,undefined)
{
    'use strict';
    var parser,ie = false;
    switch (true)
    {
        case w.DOMParser !== undefined:
            parser = new w.DOMParser();
        break;
        case new w.ActiveXObject("Microsoft.XMLDOM") !== undefined:
            parser = new w.ActiveXObject("Microsoft.XMLDOM");
            parser.async = false;
            ie = true;
        break;
        default :
            throw new Error('No parser found');
    }
    return function(xmlString)
    {
        if (ie === true)
        {//return DOM
            parser.loadXML(xmlString);
            return parser;
        }
        return parser.parseFromString(xmlString,'text/xml');
    };
})(this);
//usage:    
var newDom = parseXML(yourString);
var allTags = newDom.getElementsByTagName('*');
for(var i=0;i<allTags.length;i++)
{
    if (allTags[i].tagName.toLowerCase() === 'span')
    {//if all you want to work with are the spans:
        if (allTags[i].hasChildNodes())
        {
            //this span has nodes inside, don't apply regex:
            continue;            
        }         
        allTags[i].innerHTML = allTags[i].innerHTML.replace(/[.,?!'"]+/g,'');
    }
}

Это должно помочь вам на вашем пути. У вас все еще есть доступ к DOM, поэтому всякий раз, когда вы найдете строку, которая нуждается в фильтрации/замене, вы можете ссылаться на node с помощью allTags[i] и заменять содержимое.
Обратите внимание, что циклирование всех элементов не является рекомендуется, но мне действительно не хотелось делать всю работу за вас;-). Вам нужно будет проверить, какой тип node вы обрабатываете:

if (allTags[i].tagName.toLowerCase() === 'span')
{//do certain things
}
if (allTags[i].tagName.toLowerCase() === 'html')
{//skip
    continue;
}    

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

Ответ 2

Изменить. Как отметил Элиас, собственный JScript не поддерживает lookaheads. Я оставлю это на случай, если кто-то еще ищет что-то подобное, просто знайте.

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

(?<=>.*?)[,."'](?=.*<)

Структура:

1. (?<=>.*?)  -->  The match(es) must have ">" followed by any characters
2. [,."']     -->  Matches for the characters:  ,  .  "  '
3. (?=.*<)    -->  The match(es) must have any characters then "<" before it

Это по существу означает, что он будет соответствовать любому из символов, которые вы хотите, между набором > <.

Как я уже сказал, в комментариях я бы предложил, чтобы Point проанализировал HTML с помощью инструмента, предназначенного для этого, и просмотрел результаты с помощью регулярного выражения [,."'].

Ответ 3

Дэн, воскресив этот вопрос, потому что у него было простое решение, о котором не упоминалось. (Нашел свой вопрос, проведя некоторое исследование для заданий по поиску регулярных выражений.)

Решение парсера было отличным. Со всеми отказами об использовании regex для синтаксического анализа html я хотел бы добавить простой способ сделать то, что вы хотели с регулярным выражением в Javascript.

Регулярное выражение очень просто:

<[^>]*>|([.,"'])

Левая часть чередования соответствует полному тегу. Мы проигнорируем эти матчи. Правая сторона сопоставляет и фиксирует пунктуацию для группы 1, и мы знаем, что они являются правильной пунктуацией, потому что они не соответствовали выражению слева.

В эта демонстрация, глядя в нижнюю правую панель, вы можете видеть, что только правая пунктуация захватывается в группу 1.

Вы сказали, что хотите вставить пунктуацию в <span>. Этот код Javascript сделает это. Я заменил <tags> на {tags}, чтобы убедиться, что пример отображается в браузере.

<script>
var subject = 'true ,she said. {tag \" . ,}';
var regex = /{[^}]*}|([.,"'])/g;
replaced = subject.replace(regex, function(m, group1) {
    if (group1 == "" ) return m;
    else return "&lt;span&gt;" + group1 + "&lt;/span&gt;";
});
document.write(replaced);
</script>

Здесь живая демонстрация

Ссылка