2011-09-23 37 views
6

Tôi đang tìm một hàm javascript đủ thông minh để xóa câu cuối cùng của một đoạn văn bản dài (một đoạn thực tế). Một số ví dụ văn bản để hiển thị mức độ phức tạp:Javascript (jQuery) xóa câu cuối cùng của văn bản dài

<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> 

Bây giờ tôi có thể chia trên . và loại bỏ các mục cuối cùng của mảng nhưng điều đó sẽ không làm việc cho câu kết thúc với ? hoặc ! và một số câu kết thúc với dấu ngoặc kép như something: "stuff."

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

Làm cách nào để thực hiện việc này? Thuật toán thích hợp là gì?

Sửa - Bằng văn bản dài tôi có nghĩa là tất cả các nội dung trong đoạn văn của tôi và bởi câu tôi muốn nói một câu thực tế (không phải là một dòng), vì vậy trong ví dụ của tôi câu cuối cùng là: He later described it as: "Something insane." Khi một trong đó là loại bỏ, người tiếp theo là She did not know, "I think we should move past the fence!", she quickly said."

+0

Xác định "câu cuối cùng" và "chuỗi dài". Nếu bạn đang tìm phương pháp giới hạn số dòng trong văn bản, hãy xem ** [câu trả lời này] (http://stackoverflow.com/questions/7519337/given-a-textarea-is-there-a- chiều dài tới hạn-giới hạn/7521855 # 7521855) **. –

+0

Đã chỉnh sửa câu hỏi của tôi, bằng câu tôi có nghĩa là một câu thực, xem ở trên. :) – bartolsthoorn

+0

*** Anh ta sau này đã mô tả nó là: "Một cái gì đó điên rồ." *** Tôi không phải là Thiếu tá Anh .. nhưng điều này có đúng không? hoặc nó nên là *** Ông sau đó mô tả nó như là, "Cái gì đó điên" *** – rlemon

Trả lời

2

Xác định quy tắc của bạn: [.!?] // 1. Một câu Bắt đầu với một bức thư Capital // 2. Một câu được trước bởi không có gì hay, nhưng không [,:;] // 3. Câu có thể được đặt trước bằng dấu ngoặc kép nếu không được định dạng đúng, chẳng hạn như ["'] // 4. Câu có thể không chính xác trong trường hợp này nếu từ sau báo giá là Đặt tên cho

Bất kỳ Rules thêm

Xác định mục đích của bạn: // 1. Hủy bỏ câu cuối cùng

Giả định: Nếu bạn bắt đầu từ ký tự cuối cùng trong chuỗi văn bản và làm việc trở về trước, sau đó bạn muốn xác định sự khởi đầu của câu như: 1. Chuỗi văn bản trước ký tự là [.?!] HOẶC 2. Chuỗi văn bản trước ký tự là ["'] và bắt đầu bằng một chữ cái viết hoa 3. Mọi dấu [.] Đứng trước dấu cách 4. Chúng tôi không sửa lỗi cho các thẻ html 5. Các giả định này không mạnh mẽ và sẽ cần phải được điều chỉnh thường xuyên

Giải pháp có thể: Đọc trong chuỗi của bạn và chia nhỏ ký tự khoảng trắng để cung cấp cho chúng tôi khối chuỗi để xem xét ngược lại.

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

Nếu chuỗi của bạn là:

Blabla, một số văn bản hơn ở đây. Đôi khi mã html cơ bản được sử dụng nhưng điều đó không nên làm cho "lựa chọn" của câu khó hơn! Tôi nhìn lên cửa sổ và thấy một chiếc máy bay bay qua. Tôi hỏi điều đầu tiên xuất hiện trong đầu: "Nó đang làm gì ở đó?" Cô ấy không biết, "Tôi nghĩ chúng ta nên vượt qua hàng rào!", Cô nhanh chóng nói. Sau đó ông mô tả nó là: "Một cái gì đó điên rồ."

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."'; 

Sau đó, mảng của bạn trong characterGroups sẽ là:

["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,"] 

Lưu ý:các '' thẻ và những người khác sẽ được loại bỏ bằng cách sử dụng phương pháp .text() trong jQuery

Mỗi khối được theo sau bởi một khoảng trắng, vì vậy khi chúng tôi đã xác định vị trí bắt đầu câu của chúng tôi (theo chỉ số mảng), chúng tôi sẽ biết chỉ số nào có và chúng ta có thể chia chuỗi gốc trong ocation nơi không gian chiếm chỉ mục đó từ cuối câu.

Cho mình một biến để đánh dấu nếu chúng tôi nhận thấy nó hay không và một biến để giữ vị trí chỉ số của các phần tử mảng chúng tôi xác định là nắm giữ sự bắt đầu của câu cuối cùng:

var found = false; 
var index = null; 

Vòng qua mảng và tìm kiếm bất kỳ yếu tố kết thúc bằng [.!?] OR kết thúc bằng ", nơi các phần tử trước đó bắt đầu với một chữ cái viết hoa.

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++; 
} 

Nếu bạn chạy các kịch bản ở trên nó sẽ xác định đúng 'Ông' là bắt đầu câu cuối cùng

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

Bây giờ bạn có thể chạy qua chuỗi bạn đã có trước:

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. 

Run nó một lần nữa và nhận được: Blabla, một số văn bản hơn ở đây. Đôi khi mã html cơ bản được sử dụng nhưng điều đó không nên làm cho "lựa chọn" của câu khó hơn! Tôi nhìn lên cửa sổ và thấy một chiếc máy bay bay qua. Tôi hỏi điều đầu tiên xuất hiện trong đầu: "Nó đang làm gì ở đó?"

Chạy lại và nhận: Blabla, một số văn bản khác tại đây. Đôi khi mã html cơ bản được sử dụng nhưng điều đó không nên làm cho "lựa chọn" của câu khó hơn! Tôi nhìn lên cửa sổ và thấy một chiếc máy bay bay qua.

Chạy lại và nhận: Blabla, một số văn bản khác tại đây. Đôi khi mã html cơ bản được sử dụng nhưng điều đó không nên làm cho "lựa chọn" của câu khó hơn!

Chạy lại và nhận: Blabla, một số văn bản khác tại đây.

Chạy lại và nhận: Blabla, một số văn bản khác tại đây.

Vì vậy, tôi nghĩ rằng điều này khớp với những gì bạn đang tìm kiếm?

Là một chức năng:

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); 
} 

Đó là tầm thường để thực hiện một plugin cho nó nếu, nhưng hãy cẩn thận các giả định! :)

Điều này có hữu ích không?

Xin cảm ơn, AE

0

Đây là một câu hỏi hay. Tại sao bạn không tạo biến tạm thời, chuyển đổi tất cả '!' và '?' vào '.', chia biến đó temp, loại bỏ câu cuối cùng, hợp nhất mảng temp đó vào một chuỗi và lấy chiều dài của nó? Sau đó substring đoạn ban đầu cho đến chiều dài mà

+0

Hoặc hey, chỉ cần sử dụng Regex và nó là một tấn dễ dàng hơn = P – EHorodyski

+0

Trên thực tế bằng cách thay thế '." 'Ở phần cuối của một câu tôi có thể lấy đi chỉ với' /[\.!?]/ ', regexp @omnosis – bartolsthoorn

+0

Bạn vẫn gặp phải vấn đề với các câu có dấu ngoặc kép có dấu chấm câu, như trong mẫu của bạn – samiz

1

Điều này nên làm điều đó.

/* 
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

Cảm ơn bạn đã nhập mã số! – bartolsthoorn

+0

Tôi đã viết lại bài viết của bạn trong coffeescript https://gist.github.com/1270335 – bartolsthoorn

Các vấn đề liên quan