Javascript (jQuery) удалить последнее предложение длинного текста - PullRequest
6 голосов
/ 23 сентября 2011

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

<p>Blabla, some more text here. Sometimes <span>basic</span> html code is used but that should not make the "selection" of the sentence any harder! I looked up the window and I saw a plane flying over. I asked the first thing that came to mind: "What is it doing up there?" She did not know, "I think we should move past the fence!", she quickly said. He later described it as: "Something insane."</p>

Теперь я могу разделить на . и удалить последнюю запись массива, но это не сработает для предложений, заканчивающихся ? или ! инекоторые предложения заканчиваются кавычками вроде something: "stuff."

function removeLastSentence(text) {
  sWithoutLastSentence = ...; // ??
  return sWithoutLastSentence;
}

Как это сделать?Какой правильный алгоритм?

Редактировать - Под длинным текстом я подразумеваю все содержимое моего абзаца, а под предложением я имею в виду фактическое предложение (а не строку), поэтому в моем примере последнеепредложение: He later described it as: "Something insane." Когда этот удаляется, следующий - She did not know, "I think we should move past the fence!", she quickly said."

Ответы [ 3 ]

2 голосов
/ 01 октября 2011

Определите ваши правила: // 1. Предложение начинается с заглавной буквы // 2. Предложению ничего не предшествует или [.!?], Но не [,:;] // 3. Предложению может предшествовать кавычки, если они не отформатированы должным образом, например ["'] // 4. В этом случае предложение может быть неверным, если слово, следующее за кавычкой, является Именем

Есть ли дополнительные правила?

Определите свою цель: // 1. Удалить последнее предложение

Предположения: Если вы начали с последнего символа в строке текста и работали задом наперед, то вы бы идентифицировали начало предложения как: 1. Строка текста перед символом [.?!] ИЛИ 2. Строка текста перед символом является ["'] и ей предшествует заглавная буква 3. Каждому [.] Предшествует пробел 4. Мы не исправляем теги html 5. Эти предположения не являются надежными и должны регулярно корректироваться

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

var characterGroups = $('#this-paragraph').html().split(' ').reverse();

Если ваша строка:

Блабла, еще текст здесь. Иногда используется основной HTML-код, но это не должно усложнять «выбор» предложения! Я посмотрел в окно и увидел пролетавший над ним самолет. Я спросил первое, что пришло в голову: «Что он там делает?» Она не знала: «Я думаю, что мы должны пройти мимо забора!», Быстро сказала она. Позже он описал это как «Что-то безумное».

var originalString = 'Blabla, some more text here. Sometimes <span>basic</span> html code is used but that should not make the "selection" of the sentence any harder! I looked up the window and I saw a plane flying over. I asked the first thing that came to mind: "What is it doing up there?" She did not know, "I think we should move past the fence!", she quickly said. He later described it as: "Something insane."';

Тогда ваш массив в characterGroups будет:

    ["insane."", ""Something", "as:", "it", "described", "later", "He",
 "said.", "quickly", "she", "fence!",", "the", "past", "move", "should", "we",
 "think", ""I", "know,", "not", "did", "She", "there?"", "up", "doing", "it",
 "is", ""What", "mind:", "to", "came", "that", "thing", "first", "the", "asked",
 "I", "over.", "flying", "plane", "a", "saw", "I", "and", "window", "the", "up",
 "looked", "I", "harder!", "any", "sentence", "the", "of", ""selection"", "the",
 "make", "not", "should", "that", "but", "used", "is", "code", "html", "basic",
 "Sometimes", "here.", "text", "more", "some", "Blabla,"]

Примечание: теги '' и другие будут удалены с помощью метода .text () в jQuery

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

Дайте себе переменную, чтобы пометить, нашли ли мы ее или нет, и переменную для хранения позиции индекса элемента массива, который мы идентифицируем как содержащий начало последнего предложения:

var found = false;
var index = null;

Перебрать массив и найти любой элемент, заканчивающийся на [!!] ИЛИ заканчивающийся на ", где предыдущий элемент начинался с заглавной буквы.

var position     = 1,//skip the first one since we know that's the end anyway
    elements     = characterGroups.length,
    element      = null,
    prevHadUpper = false,
    last         = null;

while(!found && position < elements) {
    element = characterGroups[position].split('');

    if(element.length > 0) {
       last = element[element.length-1];

       // test last character rule
       if(
          last=='.'                      // ends in '.'
          || last=='!'                   // ends in '!'
          || last=='?'                   // ends in '?'
          || (last=='"' && prevHadUpper) // ends in '"' and previous started [A-Z]
       ) {
          found = true;
          index = position-1;
          lookFor = last+' '+characterGroups[position-1];
       } else {
          if(element[0] == element[0].toUpperCase()) {
             prevHadUpper = true;
          } else {
             prevHadUpper = false;
          }
       }
    } else {
       prevHadUpper = false;
    }
    position++;
}

Если вы запустите приведенный выше скрипт, он будет правильно определять «Он» как начало последнего предложения.

console.log(characterGroups[index]); // He at index=6

Теперь вы можете запустить строку, которая у вас была раньше:

var trimPosition = originalString.lastIndexOf(lookFor)+1;
var updatedString = originalString.substr(0,trimPosition);
console.log(updatedString);

// Blabla, some more text here. Sometimes <span>basic</span> html code is used but that should not make the "selection" of the sentence any harder! I looked up the window and I saw a plane flying over. I asked the first thing that came to mind: "What is it doing up there?" She did not know, "I think we should move past the fence!", she quickly said.

Запустите его снова и получите: Блабла, еще текст здесь. Иногда используется основной HTML-код, но это не должно усложнять «выбор» предложения! Я посмотрел в окно и увидел пролетавший над ним самолет. Я спросил первое, что пришло в голову: «Что он там делает?»

Запустите его снова и получите: Блабла, еще текст здесь. Иногда используется основной HTML-код, но это не должно усложнять «выбор» предложения! Я посмотрел в окно и увидел пролетавший над ним самолет.

Запустите его снова и получите: Блабла, еще текст здесь. Иногда используется основной HTML-код, но это не должно усложнять «выбор» предложения!

Запустите его снова и получите: Блабла, еще текст здесь.

Запустите его снова и получите: Блабла, еще текст здесь.

Итак, я думаю это соответствует тому, что вы ищете?

Как функция:

function trimSentence(string){
    var found = false;
    var index = null;

    var characterGroups = string.split(' ').reverse();

    var position     = 1,//skip the first one since we know that's the end anyway
        elements     = characterGroups.length,
        element      = null,
        prevHadUpper = false,
        last         = null,
        lookFor      = '';

    while(!found && position < elements) {
        element = characterGroups[position].split('');

        if(element.length > 0) {
           last = element[element.length-1];

           // test last character rule
           if(
              last=='.' ||                // ends in '.'
              last=='!' ||                // ends in '!'
              last=='?' ||                // ends in '?'
              (last=='"' && prevHadUpper) // ends in '"' and previous started [A-Z]
           ) {
              found = true;
              index = position-1;
              lookFor = last+' '+characterGroups[position-1];
           } else {
              if(element[0] == element[0].toUpperCase()) {
                 prevHadUpper = true;
              } else {
                 prevHadUpper = false;
              }
           }
        } else {
           prevHadUpper = false;
        }
        position++;
    }


    var trimPosition = string.lastIndexOf(lookFor)+1;
    return string.substr(0,trimPosition);
}

Сделать плагин для него тривиально, но остерегайтесь предположений! :)

Помогает ли это?

Спасибо, AE

2 голосов
/ 03 октября 2011

Это должно сделать это.

/*
Assumptions:
- Sentence separators are a combination of terminators (.!?) + doublequote (optional) + spaces + capital letter. 
- I haven't preserved tags if it gets down to removing the last sentence. 
*/
function removeLastSentence(text) {

    lastSeparator = Math.max(
        text.lastIndexOf("."), 
        text.lastIndexOf("!"), 
        text.lastIndexOf("?")
    );

    revtext = text.split('').reverse().join('');
    sep = revtext.search(/[A-Z]\s+(\")?[\.\!\?]/); 
    lastTag = text.length-revtext.search(/\/\</) - 2;

    lastPtr = (lastTag > lastSeparator) ? lastTag : text.length;

    if (sep > -1) {
        text1 = revtext.substring(sep+1, revtext.length).trim().split('').reverse().join('');
        text2 = text.substring(lastPtr, text.length).replace(/['"]/g,'').trim();

        sWithoutLastSentence = text1 + text2;
    } else {
        sWithoutLastSentence = '';
    }
    return sWithoutLastSentence;
}

/*
TESTS: 

var text = '<p>Blabla, some more text here. Sometimes <span>basic</span> html code is used but that should not make the "selection" of the text any harder! I looked up the window and I saw a plane flying over. I asked the first thing that came to mind: "What is it doing up there?" She did not know, "I think we should move past the fence!", she quickly said. He later described it as: "Something insane. "</p>';

alert(text + '\n\n' + removeLastSentence(text));
alert(text + '\n\n' + removeLastSentence(removeLastSentence(text)));
alert(text + '\n\n' + removeLastSentence(removeLastSentence(removeLastSentence(text))));
alert(text + '\n\n' + removeLastSentence(removeLastSentence(removeLastSentence(removeLastSentence(text)))));
alert(text + '\n\n' + removeLastSentence(removeLastSentence(removeLastSentence(removeLastSentence(removeLastSentence(text))))));
alert(text + '\n\n' + removeLastSentence(removeLastSentence(removeLastSentence(removeLastSentence(removeLastSentence(removeLastSentence(text)))))));
alert(text + '\n\n' + removeLastSentence('<p>Blabla, some more text here. Sometimes <span>basic</span> html code is used but that should not make the "selection" of the text any harder! I looked up the '));
*/
0 голосов
/ 23 сентября 2011

Это хороший.Почему бы вам не создать временную переменную, конвертировать все '!'а также '?'в '.', разделить эту временную переменную, удалить последнее предложение, объединить этот временный массив в строку и взять его длину?Затем подстрока исходного абзаца до этой длины

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