وصف المشكلة
تظهر بعض السلسلة الفارغة "" تقسيم سلسلة باستخدام طريقة تقسيم JavaScript ، خاصة عند استخدام التعبيرات العادية كحمد.
الأسئلة ذات الصلة
تعبيرات JavaScript العادية تنتج مجموعة سلسلة فارغة عند تجميع السلاسل؟
في السؤال أعلاه ، استخدم السائل تعبيرًا منتظمًا لتقسيم السلسلة وإنشاء سلاسل فارغة متعددة "" والرمز كما يلي:
نسخة الكود كما يلي:
'Zhang SDF أربعة طرق ASDF Wengf AA33NET S'.Split (/([/u4e00-/u9fa5] {1})/gi) ؛
// الإخراج ["" ، "Zhang" ، "SDF" ، "Four" ، "Up" ، "" ، "Law" ، "ASDF" ، "Weng" ، "" ، "" ، "Fen" ، "AA33" ، "Net" "S" S "
إذن ، ما سبب هذه الأوتار الفارغة؟
تحليل المشكلة
بعد البحث على Google ، وجدت أنه لم يكن هناك العديد من النتائج ذات الصلة. حتى لو كان هناك ، لم يكن هناك العديد من التفسيرات التفصيلية. قلت ذلك تقريبًا ثم أعطيت رابطًا لمواصفات ECMASCRIPT. يبدو أنه إذا كنت تريد معرفة السبب الحقيقي ، فيمكنك فقط عض الرصاصة والنظر إلى المعايير.
المعايير ذات الصلة
ثم ، وفقًا للممارسة الدولية ، انتقل أولاً إلى مبنى Town Town في Ecmascript.
نسخة الكود كما يلي:
string.prototype.split (فاصل ، حد)
يقدم هذا الفصل خطوات تنفيذ طريقة الانقسام بالتفصيل. إذا كنت مهتمًا ، فيمكنك قراءتها بعناية خطوة بخطوة. سأشرح فقط الخطوات المتعلقة بتوليد سلاسل فارغة هنا. إذا كان هناك أي نقاط غير لائقة ، فكل شخص مرحب به لذكرهم.
الخطوات ذات الصلة
خطوات جزئية لاستخراج:
الخطوة الأكثر أهمية في العملية بأكملها هي الدورة الثالثة عشرة ، والأشياء الرئيسية التي تقوم بها هذه الدورة على النحو التالي:
• تحديد قيم P و Q. قيم P و Q هي نفسها في بداية كل حلقة (هذه الخطوة خارج الحلقة) ؛
• استدعاء SPLITMATCH (S ، Q ، R) طريقة لتقسيم السلسلة ؛
• تنفيذ فروع مختلفة وفقًا للنتائج التي تم إرجاعها ، والفروع الرئيسية هي الفروع ؛
• ينقسم الفرع إلى 8 خطوات صغيرة لملء النتيجة التي تم إرجاعها إلى الصفيف المحدد مسبقًا أ
• في هذه الخطوات الثمانية الصغيرة ، فإن الغرض من الخطوة 1 هو إرجاع سلسلة فرعية للسلسلة الأصلية ، وموضع البدء هو p (مدرج) والموقف النهائي هو Q (المدرجة). ملاحظة: في هذه الخطوة ، سيتم إنشاء سلسلة فارغة ، وقد قمت بتمييزها على أنها اعتراض السلسلة لراحة الاقتباس أدناه.
• أضف السلسلة الفرعية من الخطوة السابقة إلى صفيف أ
• الخطوات القليلة التالية هي تحديث المتغيرات ذات الصلة ومتابعة الحلقة التالية. (الغرض من الخطوة 7 هو حفظ تجميع الالتقاط في التعبير العادي إلى المصفوفة A ، والتي لا علاقة لها بتوليد سلسلة فارغة)
Splitmatch (S ، Q ، R)
بعد ذلك ، نحتاج إلى فهم طريقة Splitmatch (S ، Q ، R). تم ذكر هذه الطريقة أدناه في مواصفات الانقسام. ما تفعله بشكل أساسي هو إجراء العمليات المقابلة وفقًا لنوع الفاصل:
• إذا كان المحدد من نوع regexp ، فاستدعاء الطريقة الداخلية لـ REGEXP [[مطابقة]] لمطابقة السلسلة. إذا فشلت المباراة ، فالفشل في العودة. خلاف ذلك ، إرجاع نتيجة MatchResult.
• إذا كان المحدد عبارة عن سلسلة ، يتم تنفيذ الحكم المطابق ، يتم إرجاع الفشل ، ويتم إرجاع نوع MatchResult بنجاح.
MatchResult
في الخطوات المذكورة أعلاه ، يتم تقديم متغير من النوع MatchResult. من خلال البحث عن المستند ، وجد أن المتغيرات من هذا النوع لها سمتان EndIndex والتقاط. قيمة EndIndex هي الموضع الذي يطابق السلسلة بالإضافة إلى 1. يمكن فهم التقاطات على أنها صفيف. عندما يكون المحدد تعبيرًا منتظمًا ، فإن العناصر الموجودة بداخلها هي القيم التي التقطتها المجموعة ؛ عندما يكون المحدد سلسلة ، فهي صفيف فارغ.
التالي
يمكننا أن نرى من الخطوات المذكورة أعلاه أن السلسلة المقسمة يتم إنشاؤها في خطوة اعتراض السلسلة (باستثناء التقاط مجموعة التعبيرات العادية). وظيفتها هي اعتراض السلسلة بين البداية المحددة (المدرجة) والموقف النهائي (المدرجة) ، لذلك متى ستعود ""؟ هناك حالة خاصة حيث تكون قيم موضع البدء والموقف النهائي متساويين ، وهو مجرد تخمين ، لأن المواصفات لا تعطي خطوات المواصفات لاعتراض السلسلة.
لقد جئنا جميعًا إلى هنا ، لماذا لا نأخذ خطوة إلى الأمام؟
لذلك ، حاولت البحث عن بعض رمز مصدر V8 لمعرفة ما إذا كان بإمكاني العثور على طريقة تنفيذ محددة. لقد وجدت الرمز ذي الصلة ، رابط رمز المصدر
إليكم بعضهم:
نسخة الكود كما يلي:
الوظائف STRINGSPLITJS (فاصل ، حد) {
...
...
// المحدد عبارة عن سلسلة
if (! is_regexp (فاصل)) {
var explator_string = to_string_inline (فاصل) ؛
if (limit === 0) return [] ؛
// ECMA-262 تقول أنه إذا كان الفاصل غير محدد ، فيجب أن تكون النتيجة
// كن مجموعة من الحجم 1 تحتوي على السلسلة بأكملها.
if (is_unded (فاصل)) إرجاع [الموضوع] ؛
var explator_length = explator_string.length ؛
// الفاصل عبارة عن سلسلة فارغة ، تُرجع مجموعة الأحرف مباشرة
if (Quipator_Length === 0) return ٪ stringtoarray (الموضوع ، الحد) ؛
var result = ٪ stringsplit (الموضوع ، فاصل _string ، الحد) ؛
نتيجة العودة
}
if (limit === 0) return [] ؛
// عندما يكون المحدد تعبيرًا منتظمًا ، اتصل بـ STRINGSPLITONREGEXP
إرجاع STRINGSPLITONREGEXP (الموضوع ، فاصل ، الحد ، الطول) ؛
}
// تم حذف العديد من الرموز هنا
لقد وجدت في الكود أنه عند ملء الصفيف ، سيتم استدعاء طريقة ٪ _substring لاعتراض السلسلة. لسوء الحظ ، لم أجد تعريفه ذي الصلة. إذا كان هناك أي طلاب وجدوا ذلك ، فيرجى إخبارنا بذلك. ومع ذلك ، فقد وجدت أن طريقة STRINGSUBSTRING المقابلة لطريقة التسوق في JavaScript ستستدعي طريقة ٪ _substring وإرجاع النتيجة. ثم إذا كانت "ABC'.SubString (1،1) إرجاع" "، فهذا يعني أن طريقة ٪ _substring ستعود" "عندما يكون موضع البدء والموضع النهائي متماثلًا. يمكنك معرفة النتيجة من خلال تجربتها.
لذا ، متى سيحدث موضع البدء مساويًا لموضع النهاية (أي Q === P)؟ تابعت الخطوات المذكورة أعلاه خطوة بخطوة وأخيراً وجدت:
• عندما تتطابق السلسلة الأصلية مع المحدد مرة واحدة ، وبعد ذلك مباشرة ، يطابق الموضع التالي من السلسلة S أيضًا المحدد. على سبيل المثال: 'abbbc'.split (' b ') ،' abbbc'.split (/(b) {1}/)
• حالة أخرى هي أن إحدى الشخصيات أو عدة أحرف في بداية سلسلة تتطابق مع الفاصل. على سبيل المثال: 'abc'.split (' a ') ،' abc'.split (/ab/)
• هناك حالة أخرى حيث تتطابق إحدى الأوتار أو عدة أو سلاسل في نهاية السلسلة مع المحدد ، والخطوة ذات الصلة هي الخطوة 14.
على سبيل المثال: 'abc'.split (' c ') ،' abc'.split (/bc/)
بالإضافة إلى ذلك ، عند استخدام التعبيرات العادية كحدد ، قد تظهر غير محددة في النتيجة التي تم إرجاعها.
على سبيل المثال: 'abc'.split (/(d)*/)
دعونا نلقي نظرة على المثال في البداية. هل يرضي المواقف المذكورة أعلاه؟
خارج الموضوع
هذه هي المرة الأولى التي قرأت فيها المواصفات القياسية لـ ECMAScript بعناية. عملية القراءة مؤلمة للغاية بالفعل ، لكن بعد فهمها ، أشعر بالسعادة الشديدة. شكرا لك على هذا السؤال وسؤال المتابعة.
بالمناسبة ، عند استخدام تعبير منتظم كفاصل ، سيتم تجاهل المعدل العالمي G ، وهو أيضًا مكسب إضافي.