النصوص واستيفاء النصوص
إنشاء النصوص في Dart
النصوص هي أحد أكثر أنواع البيانات استخداماً في أي لغة برمجة. في Dart النص هو تسلسل من وحدات كود UTF-16 مما يعني أنه يدعم الأحرف الدولية والرموز التعبيرية والرموز الخاصة مباشرة. يمكنك إنشاء النصوص باستخدام علامات اقتباس مفردة أو مزدوجة أو ثلاثية.
النصوص الحرفية
void main() {
// علامات اقتباس مفردة (مفضلة في Dart)
String greeting = 'مرحبا بالعالم!';
// علامات اقتباس مزدوجة (صالحة أيضاً)
String message = "أهلا بك في Dart";
// كلاهما متطابق -- اختر أسلوباً واحداً وكن متسقاً
print(greeting); // مرحبا بالعالم!
print(message); // أهلا بك في Dart
}
أحرف الهروب
أحياناً تحتاج لتضمين أحرف خاصة داخل نص. استخدم الشرطة المائلة العكسية (\) كحرف هروب:
تسلسلات الهروب الشائعة
void main() {
// سطر جديد
print('السطر الأول\nالسطر الثاني');
// مسافة جدولة
print('الاسم:\tإدريس');
// علامة اقتباس مفردة داخل نص بعلامات مفردة
print('It\'s a great day!');
// علامة اقتباس مزدوجة داخل نص بعلامات مزدوجة
print("قالت \"مرحبا\"");
// الشرطة المائلة نفسها
print('المسار: C:\Users\Dart');
// علامة الدولار (بدون استيفاء)
print('السعر: \$99.99');
}
النصوص الخام
إذا أردت تعطيل جميع تسلسلات الهروب ضع البادئة r قبل النص. هذا مفيد لمسارات الملفات والتعبيرات النمطية.
النصوص الخام مع بادئة r
void main() {
// نص عادي -- \n هو سطر جديد
print('مرحبا\nالعالم');
// المخرجات:
// مرحبا
// العالم
// نص خام -- \n يُعامل كنص حرفي
print(r'مرحبا\nالعالم');
// المخرجات: مرحبا\nالعالم
// مفيد لأنماط regex
String pattern = r'\d{3}-\d{4}';
print(pattern); // \d{3}-\d{4}
}
النصوص متعددة الأسطر
استخدم علامات الاقتباس الثلاثية (''' أو """) لإنشاء نصوص تمتد على عدة أسطر بدون الحاجة لـ \n:
النصوص متعددة الأسطر
void main() {
String poem = '''
الورود حمراء،
البنفسج أزرق،
Dart رائعة،
وأنت كذلك!
''';
print(poem);
}
استيفاء النصوص
استيفاء النصوص هو أحد أقوى ميزات Dart. بدلاً من دمج النصوص بعامل + تقوم بتضمين المتغيرات والتعبيرات مباشرة داخل النص باستخدام رمز $.
استيفاء المتغيرات البسيط
استخدم $variableName لإدراج قيمة متغير:
الاستيفاء الأساسي
void main() {
String name = 'إدريس';
int age = 28;
String language = 'Dart';
// مع الاستيفاء (موصى به)
print('اسمي $name وعمري $age سنة.');
print('أتعلم $language!');
// بدون استيفاء (غير موصى به)
print('اسمي ' + name + ' وعمري ' + age.toString() + ' سنة.');
}
+. إنه أنظف وأكثر قراءة ويتجنب الحاجة لاستدعاء .toString() يدوياً على القيم غير النصية.استيفاء التعبيرات
استخدم ${expression} لأي شيء أكثر تعقيداً من اسم متغير بسيط -- الحسابات أو استدعاءات الدوال أو الوصول للخصائص:
استيفاء التعبيرات مع ${}
void main() {
int a = 10;
int b = 20;
// تعبير حسابي
print('مجموع $a و $b هو ${a + b}');
// المخرجات: مجموع 10 و 20 هو 30
// استدعاءات الدوال
String name = 'إدريس صالح';
print('أحرف كبيرة: ${name.toUpperCase()}');
// الوصول للخصائص
List<int> numbers = [1, 2, 3, 4, 5];
print('القائمة تحتوي ${numbers.length} عناصر');
// تعبير شرطي
int score = 85;
print('النتيجة: ${score >= 60 ? "ناجح" : "راسب"}');
}
دمج النصوص
رغم تفضيل الاستيفاء تدعم Dart عدة طرق لدمج النصوص:
طرق دمج النصوص
void main() {
// 1. باستخدام عامل +
String first = 'مرحبا';
String second = 'بالعالم';
String combined = first + ' ' + second;
print(combined); // مرحبا بالعالم
// 2. نصوص حرفية متجاورة (تُدمج تلقائياً)
String auto = 'مرحبا '
'بالعالم '
'من Dart';
print(auto); // مرحبا بالعالم من Dart
// 3. StringBuffer لعمليات الدمج الكثيرة (فعال)
var buffer = StringBuffer();
buffer.write('مرحبا');
buffer.write(' ');
buffer.write('بالعالم');
print(buffer.toString()); // مرحبا بالعالم
}
StringBuffer بدلاً من +. عامل + ينشئ كائن String جديداً في كل مرة بينما StringBuffer يعدل نفس المخزن المؤقت مما يجعله أكثر كفاءة في استخدام الذاكرة.خصائص النصوص المفيدة
كل نص في Dart يأتي مع خصائص مفيدة:
خصائص النصوص
void main() {
String text = 'مرحبا Dart!';
print(text.length); // 11 (عدد الأحرف)
print(text.isEmpty); // false
print(text.isNotEmpty); // true
String empty = '';
print(empty.isEmpty); // true
print(empty.length); // 0
}
دوال النصوص الشائعة
توفر Dart العديد من الدوال المدمجة للعمل مع النصوص. إليك أهمها:
تحويل الحالة
void main() {
String name = 'Edrees Salih';
print(name.toUpperCase()); // EDREES SALIH
print(name.toLowerCase()); // edrees salih
}
إزالة المسافات
void main() {
String padded = ' مرحبا بالعالم! ';
print(padded.trim()); // 'مرحبا بالعالم!'
print(padded.trimLeft()); // 'مرحبا بالعالم! '
print(padded.trimRight()); // ' مرحبا بالعالم!'
}
البحث في النصوص
void main() {
String sentence = 'Dart ممتعة و Dart قوية';
print(sentence.contains('ممتعة')); // true
print(sentence.startsWith('Dart')); // true
print(sentence.endsWith('قوية')); // true
print(sentence.indexOf('Dart')); // 0 (أول ظهور)
print(sentence.lastIndexOf('Dart')); // 12 (آخر ظهور)
}
الاستبدال والتقسيم
void main() {
String text = 'Hello World';
// الاستبدال
print(text.replaceAll('World', 'Dart')); // Hello Dart
// التقسيم إلى قائمة
String csv = 'تفاح,موز,برتقال';
List<String> fruits = csv.split(',');
print(fruits); // [تفاح, موز, برتقال]
// نص فرعي
print(text.substring(0, 5)); // Hello
print(text.substring(6)); // World
}
الحشو والتكرار
void main() {
String id = '42';
// الحشو لطول أدنى
print(id.padLeft(5, '0')); // 00042
print(id.padRight(5, '-')); // 42---
// تكرار نص
String line = '=-' * 10;
print(line); // =-=-=-=-=-=-=-=-=-=-
}
مقارنة النصوص
النصوص في Dart تُقارن بمحتواها وليس بمرجعها:
مقارنة النصوص
void main() {
String a = 'Dart';
String b = 'Dart';
String c = 'dart';
print(a == b); // true (نفس المحتوى)
print(a == c); // false (حساسة لحالة الأحرف)
// مقارنة غير حساسة لحالة الأحرف
print(a.toLowerCase() == c.toLowerCase()); // true
}
تحويل الأنواع مع النصوص
التحويل بين النصوص والأنواع الأخرى مهمة شائعة:
التحويل من وإلى النصوص
void main() {
// رقم إلى نص
int age = 28;
String ageStr = age.toString();
print(ageStr); // '28'
// نص إلى رقم
String numStr = '42';
int number = int.parse(numStr);
print(number); // 42
// تحويل آمن (يُرجع null بدلاً من الطرح)
int? safe = int.tryParse('abc');
print(safe); // null (لا خطأ)
int? valid = int.tryParse('100');
print(valid); // 100
}
int.parse() أو double.parse() مع مدخلات غير صالحة سيطرح FormatException. استخدم دائماً tryParse() عند التعامل مع مدخلات المستخدم أو البيانات من مصادر خارجية لأنها تُرجع null بدلاً من التعطل.النصوص غير قابلة للتغيير
مفهوم مهم: النصوص في Dart غير قابلة للتغيير. كل عملية تبدو وكأنها تعدل نصاً تُنشئ في الواقع نصاً جديداً. النص الأصلي يبقى كما هو.
توضيح عدم قابلية التغيير
void main() {
String original = 'مرحبا';
String upper = original.toUpperCase();
print(original); // مرحبا (لم يتغير!)
print(upper); // مرحبا (نص جديد)
}
تمرين عملي
افتح DartPad وابنِ برنامجاً: (1) أنشئ متغيرات للاسم الأول واسم العائلة والعمر والمدينة. (2) استخدم استيفاء النصوص لطباعة مقدمة منسقة مثل “مرحباً أنا [الاسم] عمري [العمر] سنة من [المدينة].” (3) حوّل الاسم الكامل لأحرف كبيرة واحسب طوله. (4) قسّم نصاً من الهوايات مفصولة بفواصل إلى قائمة واطبع كل هواية. (5) استخدم tryParse لتحويل نص إلى عدد صحيح بأمان.