String interpolation

In computer programming, string interpolation (or variable interpolation, variable substitution, or variable expansion) is the process of evaluating a string literal containing one or more placeholders, yielding a result in which the placeholders are replaced with their corresponding values. It is a form of simple template processing[1] or, in formal terms, a form of quasi-quotation (or logic substitution interpretation). The placeholder may be a variable name, or in some languages an arbitrary expression, in either case evaluated in the current context.

String interpolation is an alternative to building a string via concatenation, which requires repeat quoting and unquoting;[2] or substituting into a printf format string, where the variable is far from where it is used. Consider this example in Ruby:

apples=4puts"I have #{apples} apples."# string interpolationputs"I have "+String(apples)+" apples."# string concatenationputs"I have %d apples."%apples# format string

Two types of literal expression are usually offered: one with interpolation enabled, the other without. Non-interpolated strings may also escape sequences, in which case they are termed a raw string, though in other cases this is separate, yielding three classes of raw string, non-interpolated (but escaped) string, interpolated (and escaped) string. For example, in Unix shells, single-quoted strings are raw, while double-quoted strings are interpolated. Placeholders are usually represented by a bare or a named sigil (typically $ or %), e.g. $apples or %apples, or with braces, e.g. {apples}, sometimes both, e.g. ${apples}. In some cases, additional formatting specifiers can be used (as in printf), e.g. {apples:3}, and in some cases the formatting specifiers themselves can be interpolated, e.g. {apples:width}. Expansion of the string usually occurs at run time.

يتباين دعم لغات البرمجة لدمج النصوص بشكل كبير. فبعض اللغات لا تدعم هذه الخاصية، بل تستخدم بدلاً منها دمج النصوص، أو دوال التنسيق البسيطة، أو مكتبات القوالب. ويُعدّ دمج النصوص شائعًا في العديد من لغات البرمجة التي تعتمد بشكل كبير على تمثيلات النصوص للبيانات، مثل Apache Groovy و Julia و Kotlin و Perl و PHP و Python و Ruby و Scala و Swift و Tcl ومعظم أنظمة Unix .

الخوارزميات

يوجد نوعان رئيسيان من خوارزميات توسيع المتغيرات لاستيفاء المتغيرات : [ 3 ]

  1. استبدال وتوسيع العناصر النائبة : إنشاء سلسلة نصية جديدة من السلسلة الأصلية، باستخدام عمليات البحث والاستبدال. البحث عن مرجع المتغير (العنصر النائب)، واستبداله بقيمته. لا توفر هذه الخوارزمية أي استراتيجية تخزين مؤقت.
  2. تقسيم ودمج السلاسل النصية : يتم تقسيم السلسلة النصية إلى مصفوفة، ثم دمجها مع مصفوفة القيم المقابلة، ثم دمج العناصر باستخدام عملية الربط. يمكن تخزين السلسلة النصية المقسمة مؤقتًا لإعادة استخدامها.

قضايا أمنية

قد يؤدي دمج السلاسل النصية، مثل دمج السلاسل النصية، إلى مشاكل أمنية. فإذا لم يتم تهريب بيانات إدخال المستخدم أو تصفيتها بشكل صحيح، فسيكون النظام عرضة لهجمات حقن SQL ، وحقن البرامج النصية ، وحقن كيانات XML الخارجية (XXE) ، وهجمات البرمجة النصية عبر المواقع (XSS). [ 4 ]

مثال على حقن SQL:

الاستعلام = " "SELECTx,y,zFROMTableWHEREid='$id'

إذا $idتم استبدالها بـ " "'; DELETEFROMTable;SELECT*FROMTableWHEREid=' ، فإن تنفيذ هذا الاستعلام سيؤدي إلى مسح جميع البيانات الموجودة في Table.

أمثلة

ABAP

DATA ( apples ) = 4 . WRITE | لدي { apples } apples |.

ستكون النتيجة كالتالي:

لدي 4 تفاحات

سحق

عدد التفاحات = 4 ، اطبع "لديّ $تفاحات " # أو اطبع "لديّ ${ تفاحات } تفاحات"

ستكون النتيجة كالتالي:

لدي 4 تفاحات

بو

عدد التفاحات = 4 ، اطبع ( "لديّ $(تفاحة) تفاحة" ) # أو اطبع ( "لديّ {0} تفاحة" % عدد التفاحات )

ستكون النتيجة كالتالي:

لدي 4 تفاحات

ج

لا تحتوي لغة C على سلاسل نصية مُدرجة، ولكن يمكن تقريبها باستخدام sprintf()from <stdio.h>.

#include <stdio.h>#define BUFFER_SIZE 100int main () { char sentence [ BUFFER_SIZE ];int age = 20 ; float height = 5.9 ; char name [] = "Alice" ;sprintf ( sentence , "اسمي %s وعمري %d سنة، وطولي %.1f قدم." , name , age , height ); printf ( sentence ); // يطبع: // اسمي أليس، وعمري 20 سنة، وطولي 5.9 قدم. }

لغة سي++

على الرغم من أن السلاسل المتداخلة غير موجودة في لغة C++ ، إلا أنه يمكن تقريبها باستخدام std::formatالدوال std::print.

استيراد std ؛باستخدام std :: string ;int main () { int apples = 4 ; int bananas = 3 ;std :: println ( "لديّ {} تفاحة" , apples ); // مُحدِّدات التنسيق std :: println ( "لديّ {0} فاكهة، منها {1} تفاحة و{2} موز" , apples + bananas , apples , bananas ); // تحديد الموضع صراحةً// باستخدام std::format(): string name = "John Doe" ; int age = 20 ; string greeting = std :: format ( "مرحباً، {}! عمرك {} سنة." , name , age ); }

تم اقتراح تضمين السلاسل المُدمجة في لغة C++، استنادًا إلى سلاسل f في بايثون. يتضمن هذا الاقتراح ميزات سبق تضمينها من std::formatمكتبة fmt . [ 5 ] في هذا الاقتراح، يتم تحويل كل سلسلة f إلى استدعاء دالة جديدة std::make_formatted_string().

استيراد std ؛باستخدام std :: string ؛ باستخدام std :: string_view ؛int calculate ( int x ) { // ... }string represent ( string_view prefix , int bits ) { return f "{prefix}-{__LINE__}: got {calculate(bits)} for {bits:#06x}" ; }void display ( string_view prefix , int bits ) { std :: print ( f "{prefix}-{__LINE__}: got {calculate(bits)} for {bits:#06x}" ); }

سي شارب

int apples = 4 ; int bananas = 3 ;Console.WriteLine ( "لديّ {تفاحات} تفاحة" ); Console.WriteLine ( " لديّ { تفاحات + موز} فاكهة" ) ;

[ 6 ]

ستكون النتيجة كالتالي:

لدي 4 تفاحات، ولدي 7 فواكه

ويمكن القيام بذلك أيضًا باستخدام String.Format().

int apples = 4 ; int bananas = 3 ;Console.WriteLine ( String.Format ( " لديّ {0} تفاحة و{1} موزة. " , apples , bananas ) ) ;

لغة ترميز ColdFusion

صيغة كتابة البرامج النصية للغة ترميز ColdFusion (CFML):

عدد التفاحات = 4 ؛ اكتب المخرجات ( "لدي #تفاحة# تفاحة" 

صيغة الوسم:

<cfset apples = 4 > <cfoutput> لدي # تفاح # تفاح </cfoutput>

ستكون النتيجة كالتالي:

لدي 4 تفاحات

كوفي سكريبت

عدد التفاحات = ثم يتم تسجيل رسالة "لديّ #{ تفاحة } تفاحة" في وحدة التحكم .

ستكون النتيجة كالتالي:

لدي 4 تفاحات

دارت

int apples = 4 , bananas = 3 ; print ( 'لديّ $ تفاحة تفاحة .' ); print ( 'لديّ ${ تفاحة + موز } فاكهة.' );

ستكون النتيجة كالتالي:

لديّ 4 تفاحات. لديّ 7 فواكه.

يذهب

على الرغم من وجود بعض المقترحات المتعلقة باستيفاء السلاسل (والتي تم رفضها)، [ 7 ] [ 8 ] [ 9 ] اعتبارًا من عام 2025لا تحتوي لغة Go على سلاسل نصية مُدمجة.

ومع ذلك، يمكن تقريبها باستخدام fmt.Sprintf().

استيراد "fmt"func main () { // message is of type string message := fmt.Sprintf ( " My name is %s and I am %d years old." , " John Doe " , 20 ) fmt.Println ( message ) }

رائع

في لغة Groovy، تُعرف السلاسل المُدمجة باسم GStrings: [ 10 ]

تعريف الجودة = "بطل خارق" العمر النهائي = 52 تعريف الجملة = "المطور ذو جودة عالية إذا كان عمره 42 عامًا أو أقل، شابًا، أو خبيرًا" طباعة الجملة

ستكون النتيجة كالتالي:

المطور يصبح بطلاً خارقاً إذا كان خبيراً.

هاكس

var apples = 4 ; var bananas = 3 ; trace ( 'لديّ $ تفاحات تفاحات .' ); trace ( 'لديّ ${ تفاحات + موزات } فواكه.' );

ستكون النتيجة: [ 11 ]

لديّ 4 تفاحات. لديّ 7 فواكه.

جافا

كانت جافا تحتوي على سلاسل نصية مُدمجة كميزة تجريبية في جافا 21 وجافا 22. ويمكن للمرء استخدام الثابت STR الخاص بـ java.lang.StringTemplate مباشرةً.

package org.wikipedia.examples ;enum Stage { TEST , QA , PRODUCTION }سجل النشر ( صورة UUID ، مرحلة المرحلة ) {}public class Example { public static void main ( String [] args ) { Deploy deploy = new Deploy ( UUID . randomUUID (), Stage . TEST ) STR . "جارٍ تثبيت {deploy.image()} على المرحلة {deploy.stage()} ..." Deploy deploy = new Deploy ( UUID . randomUUID (), Stage . PRODUCTION ) STR . "جارٍ تثبيت {deploy.image()} على المرحلة {deploy.stage()} ..." } }

تمت إزالتها في Java 23 بسبب مشاكل في التصميم. [ 12 ]

وإلا، يمكن تقريب السلاسل المتداخلة باستخدام هذه String.format()الطريقة.

package org.wikipedia.examples ;public class Example { public static void main ( String [] args ) { int apples = 3 ; int bananas = 4 ;String sentence = String.format ( " لديّ % d فاكهة ، منها %d تفاح و%d موز." , apples + bananas , apples , bananas ) ; System.out.println ( sentence );String name = "John Doe" ; int age = 20 ; System . out . printf ( "اسمي %s، وعمري %d سنة." , name , age ); } }

جافا سكريبت/تايب سكريبت

تدعم لغتا جافا سكريبت وتايب سكريبت ، وفقًا لمعيار ECMAScript`` 2015 (ES6)، عملية دمج النصوص باستخدام علامات التنصيص المائلة . تُعرف هذه الميزة باسم "النصوص القالبية" . [ 13 ] إليك مثال:

const apples : number = 4 ; const bananas : number = 3 ; console.log ( ` لديّ $ { apples } تفاحة` ); console.log ( ` لديّ ${ apples + bananas } فاكهة` ) ;

ستكون النتيجة كالتالي:

لدي 4 تفاحات، ولدي 7 فواكه

يمكن أيضًا استخدام القوالب النصية للسلاسل النصية متعددة الأسطر:

console.log ( ` هذا هو السطر الأول من النص. هذا هو السطر الثاني من النص.` ) ;

ستكون النتيجة كالتالي:

هذا هو السطر الأول من النص. هذا هو السطر الثاني من النص.

جوليا

تفاح = 4 موز = 3 اطبع ( "لديّ $ تفاح تفاح و $ موز موز، مما يجعل $ ( تفاح + موز ) قطعة فاكهة إجمالاً." )

ستكون النتيجة كالتالي:

لدي 4 تفاحات و3 موزات، أي ما مجموعه 7 قطع من الفاكهة.

كوتلين

fun main () { val quality : String = "superhero" val apples : Int = 4 val bananas : Int = 3 val sentence : String = "المطور يتمتع بجودة $ . لدي ${ apples + bananas } فاكهة" println ( sentence ) }

ستكون النتيجة كالتالي:

المطور بطل خارق. لديّ سبع ثمرات.

نيميرل

def apples = 4 ; def bananas = 3 ; Console.WriteLine ( $ "لديّ $apples تفاح." ) ; Console.WriteLine ( $ "لديّ $(apples + bananas) فاكهة . " ) ;

كما يدعم ميزات التنسيق المتقدمة، مثل:

def fruit = [ "apple" , "banana" ]; Console . WriteLine ( $ < #I have ..$(fruit; "\n"; f => f + "s")#>);

ستكون النتيجة كالتالي:

تفاح وموز

نيم

توفر لغة Nim إمكانية استيفاء السلاسل النصية عبر وحدة strutils. أما السلاسل النصية المنسقة، المستوحاة من سلاسل F في لغة Python، فتُقدم عبر وحدة strformat، حيث يتحقق ماكرو strformat من أن سلسلة التنسيق سليمة من حيث البنية والنوع، ثم تُحوّل إلى شفرة مصدرية في Nim أثناء وقت الترجمة.

استوردنا مكتبتي strutils و strformat. ثم حددنا متغيرين: apples = 4 و bananas = 3. بعد ذلك ، طبعنا "لديّ تفاح بقيمة 1 دولار " . ثم طبعنا "لديّ {تفاح} تفاحة". ثم طبعنا "لديّ {تفاح + موز} فاكهة".# تنسيق صدى متعدد الأسطر " "" لدي { تفاح } تفاح" " "# تصحيح تنسيق echo fmt"لدي {apples=} تفاح"# أحرف فتح وإغلاق مخصصة echo fmt ( "I have (apples) {apples}" , '(' , ')' )# علامة الخط المائل العكسي داخل السلسلة النصية المنسقة echo fmt" "" { " yep \ nope" } "" "

ستكون النتيجة كالتالي:

لدي 4 تفاحات، لدي 4 تفاحات، لدي 7 فواكه، لدي 4 تفاحات، لدي تفاحات = 4 تفاحات، لدي 4 {تفاحات} ، نعم، افتح

نيكس

let numberOfApples = "4" ; in "I have ${ numberOfApples } apples"

ستكون النتيجة كالتالي:

لدي 4 تفاحات

باراسيل

const Apples := 4 const Bananas := 3 Println ( "لديّ `(Apples) تفاحة.\n" ) Println ( "لديّ `(Apples+Bananas) فاكهة.\n" )

ستكون النتيجة كالتالي:

لديّ 4 تفاحات. لديّ 7 فواكه.

بيرل

my $apples = 4 ; my $bananas = 3 ; print "لديّ $apples تفاحة.\n" ; print "لديّ @{[$apples+$bananas]} فاكهة.\n" ; # يستخدم استيفاء مصفوفة بيرل (@).

ستكون النتيجة كالتالي:

لدي 4 تفاحات. لدي 7 فاكهة.

PHP

<?php $apples = 5 ; $bananas = 3 ; echo "يوجد $apples تفاح و $bananas موز. \n " ; echo "لدي { $apples } تفاح و { $bananas } موز." ;

ستكون النتيجة كالتالي:

يوجد 5 تفاحات و3 موزات. لديّ 5 تفاحات و3 موزات.

بايثون

يدعم بايثون استيفاء السلاسل النصية بدءًا من الإصدار 3.6، ويُشار إليه باسم "السلاسل النصية المنسقة" أو "سلاسل f". [ 14 ] [ 15 ] [ 16 ] تبدأ هذه السلسلة النصية بعلامة اقتباس fأو Fقبل علامة الاقتباس الافتتاحية، وتستخدم الأقواس المعقوفة كعناصر نائبة.

التفاح : عدد صحيح = 4 ، الموز : عدد صحيح = 3print ( f "لدي { تفاح } تفاح و { موز } موز" )

ستكون النتيجة كالتالي:

لدي 4 تفاحات و3 موزات

روبي/كريستال

عدد التفاحات = 4 ، اطبع "لديّ #{ تفاحات } تفاحة" # تطبيقات تنسيق السلسلة للمقارنة: اطبع "لديّ %s تفاحة" % تفاحات، اطبع "لديّ %{a} تفاحة" % { a : تفاحات }

ستكون النتيجة كالتالي:

لدي 4 تفاحات

الصدأ

لا تحتوي لغة Rust على خاصية استيفاء السلاسل النصية بشكل عام، ولكنها توفر وظائف مماثلة عبر وحدات الماكرو، والتي يشار إليها باسم "المعرفات الملتقطة في سلاسل التنسيق"، والتي تم تقديمها في الإصدار 1.58.0، الذي صدر في 13 يناير 2022. [ 17 ]

توفر لغة Rust إمكانية التنسيق عبر وحدة std::fmt ، والتي يتم التفاعل معها من خلال وحدات ماكرو مختلفة مثل format! و write! و print!. تُحوّل هذه الوحدات إلى كود مصدر Rust أثناء الترجمة، حيث يتفاعل كل وسيط مع مُنسِّق . يدعم المُنسِّق المعاملات الموضعية ، والمعاملات المُسماة ، وأنواع الوسائط ، وتحديد سمات التنسيق المختلفة ، واستخلاص المعرّفات من البيئة.

fn main () { let ( apples , bananas ): ( i32 , i32 ) = ( 4 , 3 ); // println! يلتقط المعرفات عند التنسيق: لا يتم استيفاء السلسلة نفسها بواسطة Rust. println! ( "يوجد {apples} تفاح و {bananas} موز." );// أو بدلاً من ذلك، باستخدام format!(): let sentence : String = format! ( "يوجد {0} تفاحة و {1} موزة." , apples , bananas ); println! ( sentence ); }

ستكون النتيجة كالتالي:

يوجد 4 تفاحات و 3 موزات.

سكالا

توفر لغة Scala 2.10 والإصدارات الأحدث منها آلية عامة لمعالجة النصوص النصية كيفما تشاء، وتدعم استيفاء النصوص باستخدام دوال الاستيفاء المدمجة s. fكما يُمكن كتابة دوال استيفاء مخصصة أو تجاوز الدوال القياسية.

المُستكمِل fهو ماكرو للمُصرِّف يُعيد كتابة سلسلة التنسيق مع التعبيرات المُضمَّنة كاستدعاء للدالة String.format. وهو يتحقق من أن سلسلة التنسيق سليمة البنية والنوع.

المُستكمِلات القياسية

تتيح خاصية استيفاء السلاسل النصية في Scala 2.10 والإصدارات الأحدث تضمين مراجع المتغيرات مباشرةً في السلاسل النصية المُعالجة. إليك مثال:

val apples = 4 val bananas = 3 // قبل Scala 2.10 printf ( "لديّ %d تفاحة\n" , apples ) println ( "لديّ %d تفاحة" format apples ) // Scala 2.10+ println ( s"لديّ $ تفاحة تفاحة " ) println ( s"لديّ ${ تفاح + موز } فاكهة" ) println ( f"لديّ $ تفاحة %d تفاحة" )

ستكون النتيجة كالتالي:

لدي 4 تفاحات

Scitter (tiscript)

في لغة Sciter، تُعتبر أي دالة يبدأ اسمها بـ $ دالة استيفاء، وبالتالي فإن الاستيفاء قابل للتخصيص وحساس للسياق:

var apples = 4 varbanans = 3 var domElement = ... ;domElement . $content ( "<p> لديّ { تفاحات } تفاحات < / p > " ); domElement . $append ( " <p> لديّ { تفاحات + موز } فواكه < /p> " );

أين

domElement . $content ( < p > لدي { تفاح } تفاح < / p >);

يتم تجميعها على النحو التالي:

domElement.html = " <p> لديّ " + apples.toHtmlString ( ) + " تفاحات</p > " ;

سنوبول

عدد التفاحات = 4 ؛ عدد الموزات = 3. الناتج = "لديّ " تفاحات " تفاحات." الناتج = "لديّ " ( تفاحات + موز ) " فاكهة."

ستكون النتيجة كالتالي:

لديّ 4 تفاحات. لديّ 7 فواكه.

سويفت

في لغة Swift ، يمكن إنشاء قيمة نصية جديدة من مزيج من الثوابت والمتغيرات والقيم الحرفية والتعبيرات عن طريق تضمين قيمها داخل قيمة نصية حرفية. [ 18 ] يتم تغليف كل عنصر يتم إدخاله في القيمة النصية الحرفية بزوج من الأقواس، مسبوقًا بشرطة مائلة عكسية.

let apples = 4 print ( "I have \ (apples) apples" )

ستكون النتيجة كالتالي:

لدي 4 تفاحات

تي سي إل

لطالما دعمت لغة أوامر الأدوات عملية استيفاء السلاسل النصية في جميع السلاسل النصية المفصولة بعلامات اقتباس.

set apples 4 puts "I have $apples apples."

ستكون النتيجة كالتالي:

لدي أربع تفاحات.

من أجل تنسيق القيم فعلياً - وليس مجرد استبدالها - توجد وظيفة تنسيق.

set apples 4 puts [ format "لديّ %d تفاحة." $apples ]

فيجوال بيسك دوت نت

ابتداءً من الإصدار 14 من Visual Basic، أصبح استيفاء السلاسل النصية مدعومًا في Visual Basic. [ 19 ]

name = " Tom " Console.WriteLine ( $ "Hello, {name}" )

ستكون النتيجة كالتالي:

مرحباً يا توم

انظر أيضاً

ملحوظات

  1. " فرض الفصل الصارم بين النموذج والعرض في محركات القوالب "، تي. بار (2004)، مؤتمر WWW2004.
  2. "الاستيفاء في بيرل" . perlmeme.org . Hardware Haven. 12 ديسمبر 2024. تم الاطلاع عليه في 30 يونيو 2026. هذا أكثر ترتيبًا بكثير من الاستخدام المتكرر لعامل الربط ..
  3. "smallest-template-system/Simplest algorithms" ، وهو برنامج تعليمي عبر الإنترنت لأنظمة القوالب العنصرية.
  4. "استيفاء السلاسل النصية الآمن" . google-caja.googlecode.com . مؤرشف من الأصل بتاريخ 19-10-2012.
  5. ^ بينجت جوستافسون، فيكتور زفيروفيتش (14 أكتوبر 2024). "استيفاء السلسلة - p3412r0" (PDF) . open-std.org . مجموعة العمل 21.
  6. "السلاسل النصية - دليل برمجة C#" . 15 مارس 2024.
  7. "اقتراح: Go 2: استيفاء السلاسل النصية #34174" . GitHub .
  8. "اقتراح: Go 2: استيفاء السلاسل النصية وتقييمها إلى سلسلة نصية وقائمة من التعبيرات #50554" . GitHub .
  9. "اقتراح: المواصفات: إضافة استيفاء بسيط للسلاسل النصية مشابه لـ Swift · المشكلة رقم 57616 · golang/go" . GitHub . تم الاسترجاع في 19 مايو 2025 .
  10. "لغة برمجة أباتشي جروفي - بناء الجملة" . groovy-lang.org . تم الاطلاع عليه بتاريخ 2021-06-20 .
  11. "هاكس - دليل - استيفاء السلاسل النصية" . هاكس - مجموعة أدوات متعددة المنصات . تم الاطلاع عليه بتاريخ 12-09-2017 .
  12. "تغييرات هامة في JDK" .
  13. "القيم الحرفية للقوالب (سلاسل القوالب) - جافا سكريبت | MDN" . 31 مايو 2024.
  14. "دليل بايثون التعليمي: 7.1.1. السلاسل النصية المنسقة" .
  15. "مرجع لغة بايثون: 2.4.3. السلاسل النصية المنسقة" .
  16. "PEP 498 -- الاستيفاء الحرفي للسلاسل النصية" .
  17. "الإعلان عن Rust 1.58.0: المعرفات الملتقطة في سلاسل التنسيق" . 2022-01-13.
  18. "السلاسل والأحرف - لغة برمجة سويفت (سويفت 5.5)" . docs.swift.org . تم الاطلاع عليه بتاريخ 2021-06-20 .
  19. كاثلين دولارد. "السلاسل النصية المُدمجة - فيجوال بيسك" . docs.microsoft.com . تم الاطلاع عليه بتاريخ 2021-06-20 .