เมื่อใช้ javascript ฉันจะนับตัวอักษรเอเชียและคำภาษาอังกฤษผสมกันได้อย่างไร

ฉันต้องใช้อักขระเอเชียผสมจำนวนหนึ่ง (สำหรับตอนนี้ สมมติว่าใช้เฉพาะคันจิจีนหรือคันจิ/ฮิระงะนะ/คาตาคานะของญี่ปุ่น) และ "ตัวอักษรและตัวเลข" (เช่น อังกฤษ ฝรั่งเศส) แล้วนับด้วยวิธีต่อไปนี้:

1) นับตัวละครเอเชียแต่ละตัวเป็น 1; 2) นับแต่ละคำตัวอักษรและตัวเลขเป็น 1;

ตัวอย่างบางส่วน:

株式会社myCompany = 4 ตัวอักษร + 1 คำ = ทั้งหมด 5 ตัวอักษร 株式会社マイECO = 7 ตัวอักษร


ความคิดเดียวของฉันจนถึงตอนนี้คือใช้:

var wordArray=val.split(/\w+/);

จากนั้นตรวจสอบแต่ละองค์ประกอบเพื่อดูว่าเนื้อหาเป็นตัวอักษรและตัวเลข (ดังนั้นนับเป็น 1) หรือไม่ (ดังนั้นใช้ความยาวของอาร์เรย์) แต่ฉันรู้สึกว่ามันไม่ฉลาดเลยจริงๆ และการนับข้อความอาจมีมากถึง 10,000 คำ ดังนั้นจึงไม่รวดเร็วนัก

ไอเดีย?


person user224513    schedule 23.02.2010    source แหล่งที่มา
comment
คุณไม่สามารถบอกอักขระเอเชียจากอักขระหลายไบต์อื่นๆ ได้   -  person shinkou    schedule 23.02.2010
comment
แน่นอนคุณสามารถ พวกเขามีค่านิยมที่แตกต่างกันออกไป   -  person Annabelle    schedule 23.02.2010
comment
ขอบคุณทุกคน. จริงๆ แล้วเราตัดสินที่: var charArray=val.match(/\w+|[^.,0-9, ゙, ゚ ]/g); การแจ้งเตือน (charArray.length); เราไม่สนใจการนับคำภาษาเอเชีย เราต้องการจำนวนตัวอักษรบวกจำนวนคำที่เป็นตัวอักษรและตัวเลข ฉันคิดว่าเราจะต้องเพิ่มโค้ดยกเว้นบางส่วน แต่นี่เป็นการเริ่มต้นที่ดี   -  person user224513    schedule 24.02.2010


คำตอบ (3)


น่าเสียดายที่ RegExp ของ JavaScript ไม่รองรับคลาสอักขระ Unicode \w ใช้กับอักขระ ASCII เท่านั้น (ปรับเปลี่ยนข้อบกพร่องของเบราว์เซอร์บางส่วน)

คุณสามารถใช้อักขระ Unicode เป็นกลุ่มได้ ดังนั้นคุณสามารถทำได้หากคุณสามารถแยกชุดอักขระแต่ละชุดที่คุณสนใจออกเป็นช่วงได้ เช่น.:

var r= new RegExp(
    '[A-Za-z0-9_\]+|'+                             // ASCII letters (no accents)
    '[\u3040-\u309F]+|'+                           // Hiragana
    '[\u30A0-\u30FF]+|'+                           // Katakana
    '[\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DBF]',   // Single CJK ideographs
'g');

var nwords= str.match(r).length;

(นี่เป็นความพยายามในการนับ 'คำ' ที่สมจริงยิ่งขึ้นสำหรับภาษาญี่ปุ่น โดยนับคะนะแต่ละประเภทเป็นคำ แน่นอนว่ายังไม่ถูกต้อง แต่อาจจะใกล้เคียงกว่าการรักษาแต่ละพยางค์เป็นคำเดียว)

แน่นอนว่ามีตัวละครอีกมากมายที่จะต้องพิจารณาหากคุณต้องการ 'ทำอย่างถูกต้อง' หวังว่าคุณจะไม่มีตัวละครนอกระนาบพูดได้หลายภาษาขั้นพื้นฐานเลย!

person bobince    schedule 23.02.2010

คุณสามารถวนซ้ำอักขระแต่ละตัวในข้อความ โดยตรวจดูอักขระแต่ละตัวเพื่อหาตัวแบ่งคำ ตัวอย่างต่อไปนี้เป็นการดำเนินการนี้ โดยนับแต่ละอักษรจีน/ญี่ปุ่น/เกาหลี (CJK) เป็นคำเดียว และถือว่าสตริงตัวอักษรและตัวเลขทั้งหมดเป็นคำเดียว

หมายเหตุบางประการเกี่ยวกับการนำไปใช้งานของฉัน:

  1. อาจไม่รองรับอักขระเน้นเสียงอย่างถูกต้อง พวกเขาอาจจะทำให้เกิดการแบ่งคำ คุณสามารถแก้ไข wordBreakRegEx เพื่อแก้ไขปัญหานี้ได้

  2. cjkRegEx ไม่รวมช่วงจุดโค้ดที่ลึกลับบางช่วง เนื่องจากต้องใช้เลขฐานสิบหก 5 หลักในการอ้างอิง และดูเหมือนว่ากลไก regex ของ JavaScript จะไม่ยอมให้คุณทำเช่นนั้น แต่คุณอาจไม่จำเป็นต้องกังวลเกี่ยวกับสิ่งเหล่านี้ เนื่องจากฉันไม่คิดว่าแบบอักษรส่วนใหญ่จะมีแบบอักษรเหล่านี้ด้วยซ้ำ

  3. ฉันจงใจละฮิระงะนะและคาตาคานะของญี่ปุ่นออกจาก cjkRegEx เนื่องจากฉันไม่แน่ใจว่าคุณต้องการจัดการสิ่งเหล่านี้อย่างไร ขึ้นอยู่กับประเภทของข้อความที่คุณกำลังติดต่อด้วย อาจเหมาะสมกว่าที่จะถือว่าสตริงของข้อความเหล่านี้เป็นคำเดียว ในกรณีนั้น คุณจะต้องเพิ่มตรรกะเพื่อให้รู้ว่าอยู่ใน "คำคานะ" เทียบกับ "คำที่เป็นตัวอักษรและตัวเลข" หากคุณไม่สนใจ คุณก็แค่เพิ่มช่วงจุดโค้ดไปที่ cjkRegEx แน่นอน คุณสามารถลองจดจำการแบ่งคำภายในสตริงคานะได้ แต่นั่นจะกลายเป็นเรื่องยากมากอย่างรวดเร็ว

ตัวอย่างการใช้งาน:

function getWordCount(text) {
  // This matches all CJK ideographs.
  var cjkRegEx = /[\u3400-\u4db5\u4e00-\u9fa5\uf900-\ufa2d]/;

  // This matches all characters that "break up" words.
  var wordBreakRegEx = /\W/;

  var wordCount = 0;
  var inWord = false;
  var length = text.length;
  for (var i = 0; i < length; i++) {
    var curChar = text.charAt(i);
    if (cjkRegEx.test(curChar)) {
      // Character is a CJK ideograph.
      // Count it as a word.
      wordCount += inWord ? 2 : 1;
      inWord = false;
    } else if (wordBreakRegEx.test(curChar)) {
      // Character is a "word-breaking" character.
      // If a word was started, increment the word count.
      if (inWord) {
        wordCount += 1;
        inWord = false;
    } else {
      // All other characters are "word" characters.
      // Indicate that a word has begun.
      inWord = true;
    }
  }

  // If the text ended while in a word, make sure to count it.
  if (inWord) {
    wordCount += 1;
  }

  return wordCount;
}

ฐานข้อมูล Unihan มีประโยชน์มากสำหรับการเรียนรู้เกี่ยวกับ CJK ใน Unicode นอกจากนี้ หน้าแรกของ Unicode ยังมีข้อมูลมากมายอีกด้วย

person Annabelle    schedule 23.02.2010
comment
ไม่มีประโยชน์มากยกเว้นตัวอย่างรหัสเทียม 1) การใช้งานตัวอย่างไม่มีวงเล็บปิดที่ส่วนท้ายของ for loop ทำให้พังทั้งหมด 2) หากคุณแก้ไขมันจะไม่นับคำภาษาอังกฤษที่ถูกต้อง 3) นอกจากนี้ยังนับคำภาษาญี่ปุ่นไม่ถูกด้วย เนื่องจากผู้เขียนไม่ใส่ฮิระงะนะและคาตาคานะ - person fotoflo; 22.11.2015

ฉันคิดว่าคุณต้องการวนซ้ำอักขระทั้งหมดและเพิ่มตัวนับทุกครั้งที่อักขระปัจจุบันอยู่ในคำอื่น (ตามคำจำกัดความของคุณ) มากกว่าคำก่อนหน้า

person Thilo    schedule 23.02.2010