문자열 보간

String interpolation

컴퓨터 프로그래밍에서 문자열 보간(또는 변수 보간, 변수 대체 또는 변수 확장)은 하나 이상의 자리 표시자를 포함하는 문자열 리터럴을 평가하는 과정으로, 자리 표시자가 해당 값으로 대체되는 결과를 산출한다. 그것은 단순한 템플릿 처리[1] 한 형태 또는 형식적인 용어로 준쿼트(또는 논리 대체 해석)의 한 형태다. 문자열 보간으로 문자열 연결에 비해 쉽고 직관적인 문자열 형식과 내용 지정이 가능하다.[2]

문자열 보간술Apache Groovy, Julia, Kotlin, Perl, PHP, Python, Ruby, Scala, Swift, Tcl 및 대부분의 Unix 쉘과 같은 많은 프로그래밍 언어에서 흔하다. 보통 두 가지 형태의 문자표현이 제공되는데, 하나는 보간이 가능한 형태, 다른 하나는 (원시 문자열이 없는 형태)이다. 자리 표시자는 일반적으로 맨 문자 또는 명명된 시기로 표시된다(일반적으로). $ 또는 %(), 예: $placeholder 또는 %123. 문자열의 확장은 보통 런타임에 발생한다.

변형

일부 언어는 문자열 보간법을 제공하지 않고, 대신 한 매개변수가 인쇄 f 형식 문자열인 표준 함수를 제공하며, 다른 언어는 각 자리 표시자에 대한 값을 제공한다.

Ruby는 그것을 사용한다. # 보간 기호 및 변수뿐만 아니라 모든 식을 보간할 수 있다. 다른 언어는 다음과 같은 특수 형식 지정 함수를 사용하여 보다 고급 보간법을 지원할 수 있다. printf첫 번째 인수인 형식은 나머지 인수가 대체되는 패턴을 지정한다.

알고리즘

가변 보간용 확장 변수 알고리즘에는 크게 두 가지 유형이 있다.[3]

  1. 자리 표시자 바꾸기 확장: 원래 문자열에서 찾기 대체 작업을 통해 새 문자열을 작성하십시오. 가변 참조(placeholder)를 찾아 변수 값으로 대체하십시오. 이 알고리즘은 캐시 전략을 제공하지 않는다.
  2. 문자열 분할 결합: 문자열을 배열로 분할하고 해당 값의 배열과 병합한 다음 연결하여 항목을 결합하십시오. 분할된 문자열을 캐시하여 재사용할 수 있다.

보안 문제

끈 연결과 같은 끈 보간술은 보안 문제를 초래할 수 있다. 사용자 입력 데이터가 부적절하게 유출되거나 필터링되면 시스템은 SQL 주입, 스크립트 주입, XML 외부 엔티티 주입(XXE), 사이트스크립팅(XSS) 공격에 노출된다.[4]

SQL 주입 예제:

쿼리 = "SELECT x, y, z FROM Table WHERE id='$id' " 

"'; DELETE FROM Table; SELECT * FROM Table WHERE id='로 대체된 경우, 이 쿼리를 실행하면 표의 모든 데이터가 삭제된다.

다음 Perl 코드는 PHP에서 동일하게 작동한다.

달러명 = "앨리스"; 인쇄하다 "${name}이 사람들 무리에게 헬로월드를 말했다."; 

출력: Alice said Hello World to the crowd of people.

ABAP

데이터(사과) = 4. 쓰기  있습니다 { 사과 } 사과 . 

산출물은 다음과 같다.

나는 4개의 사과를 가지고 있다. 

배쉬

사과=4 메아리치다 "있다. 달러화 사과." # 또는 메아리치다 "있다. ${사과} 사과." 

산출물은 다음과 같다.

나는 4개의 사과를 가지고 있다. 

Boo

사과 = 4 인쇄하다("나는 사과를 가지고 있다.") # 또는 인쇄하다("나는 {0}개의 사과를 가지고 있다" % 사과) 

산출물은 다음과 같다.

나는 4개의 사과를 가지고 있다. 

C#

시합을 하다 사과 = 4; 시합을 하다 바나나 = 3;  콘솔.WriteLine($"나는 {apples}개의 사과를 가지고 있다"); 콘솔.WriteLine($"나는 {apple + 바나나}개의 과일을 가지고 있다"); 

[5]

산출물은 다음과 같다.

나는 사과가 4개 있고 과일 7개가 있다. 

콜드퓨전 마크업 언어

CFML(ColdFusion Markup Language) 스크립트 구문:

사과 = 4; writeOutput("있다. ### 사과."); 

태그 구문:

<cfset 사과 = 4> <cfoutput>나는 #apples# approutput. 

산출물은 다음과 같다.

I have 4 apples 

커피스크립트

사과 = 4 위로하다.통나무를 하다 "있다. #{사과} 사과." 

산출물은 다음과 같다.

나는 4개의 사과를 가지고 있다. 

다트

인트로 사과 = 4, 바나나 = 3; 인쇄하다('나는 사과 한 개를 가지고 있다.'); 인쇄하다('나는 ${apples+bananas}의 과일을 가지고 있다.'); 

산출물은 다음과 같다.

나는 4개의 사과를 가지고 있다. 나는 7개의 과일을 가지고 있다.  

가다

랑그 := "골랑" 사과 := 3 fmt.프린트프("나는 %s 개발자다.\n", 랑그) fmt.프린트프("나는 %d개의 사과를 가지고 있다.\n", 사과) 

산출물은 다음과 같다.

나는 골랑 개발자다. 나는 사과가 3개 있다.  

그루비

그루비에서 보간 문자열을 GString이라고 한다.[6]

반항하다 품질의 = "superhero" 최종의 나이를 먹다 = 52 반항하다 형을 언도하다 = "개발자는 ${{age <= 42 ?}}}}이면 $의 품질이다.젊은" : "노련한"}" 인쇄하다 형을 언도하다 

산출물은 다음과 같다.

개발자는 만약 그가 경험이 있다면 슈퍼히어로다. 

헥시

var apples = 4; var anna = 3; trace('I have $apples apples'), trace('${apples+banananas});; 

산출물은 다음과 같다.

나는 사과가 4개 있다. 나는 7개의 과일을 가지고 있다.  

[7]

자바

진정한 보간 문자열이 부족한 자바는 해결책으로 도우미 기능을 사용한다.

Java 버전 5 이상에서는 정적 메서드 String.format 보간 작업에 사용할 수 있음:

인트로 사과 = 4; 인트로 바나나 = 3; 시스템.밖으로.인쇄하다(.형식을 갖추다(" %s 사과와 %s 바나나를 가지고 있다", 사과, 바나나)); 시스템.밖으로.인쇄하다(.형식을 갖추다(" %s 과일을 가지고 있다", 사과 + 바나나)); 

Java 버전 1.1 이상에서는 MessageFormat 클래스는 자리 표시자를 사용하여 객체 집합을 포맷할 수 있음:

오브젝트[] 테스타르크스 = {.ValueOf(3), "마이디스크"};  메시지 형식 형체를 이루다 = 새로운 메시지 형식(   "디스크 \"{1}\"에는 {0}개의 파일이 포함되어 있다.");  시스템.밖으로.인쇄하다(형체를 이루다.형식을 갖추다(테스타르크스)); 

자바스크립트

자바스크립트ECMAScript 2015(ES6) 표준 기준으로 백틱을 사용한 문자열 보간법을 지원한다. ``. 이 특징은 템플릿 리터럴이라고 불린다.[8] 예를 들면 다음과 같다.

경시하다 사과 = 4; 경시하다 바나나 = 3; 위로하다.통나무를 하다(가지고 있다 ${사과} 사과); 위로하다.통나무를 하다(가지고 있다 ${사과 + 바나나} 과실); 

산출물은 다음과 같다.

나는 사과 4개, 과일 7개가 있다. 

템플릿 리터럴은 멀티라인 문자열에도 사용할 수 있다.

위로하다.통나무를 하다(이것은 텍스트의 첫 번째 줄이다. 이것은 텍스트의 두 번째 줄이다.`); 

산출물은 다음과 같다.

이것이 텍스트의 첫 줄이다. 이것은 텍스트의 두 번째 줄이다.  

줄리아.

사과 = 4 바나나 = 3 인쇄하다("있다. 달러화 사과와 달러화 바나나, 만들기 $(사과 + 바나나) 총과일조각.") 

산출물은 다음과 같다.

나는 사과 4개와 바나나 3개를 가지고 있어, 총 7조각의 과일을 만들고 있어.  

코틀린

발랄하게 하다 품질의 = "superhero" 발랄하게 하다 사과 = 4 발랄하게 하다 바나나 = 3 발랄하게 하다 형을 언도하다 = "개발자는 a이다. $품질의나는 가지고 있다. ${사과 + 바나나} 과일." 인쇄하다(형을 언도하다) 

산출물은 다음과 같다.

개발자는 슈퍼히어로다. 나는 7개의 과일을 가지고 있다. 

네멜레

반항하다 사과 = 4; 반항하다 바나나 = 3; 콘솔.WriteLine($"나는 사과가 $apples 있어."); 콘솔.WriteLine($"나에겐 $(애플+바나나) 과일이 있어.); 

또한 다음과 같은 고급 포맷 기능도 지원한다.

반항하다 과실 = ["사과", "banana"]; 콘솔.WriteLine($<#나는..$(과일; "\n"; f => f + "s")#]; 

산출물은 다음과 같다.

사과 바나나 

차세대 쉘

권장 구문은 다음과 같다. ${expr} 그럼에도 불구하고 $var 또한 다음과 같이 지원된다.

퀄리티 = "슈퍼히어로" 사과 = 4 바나나 = 3문장 = "개발자는 달러 퀄리티.${apples + 바나나} 과일" 에코를 가지고 있다. 

산출물은 다음과 같다.

개발자는 슈퍼히어로다. 나는 7개의 과일을 가지고 있다. 

Nim은 스트럿힐 모듈을 통해 스트링 보간 기능을 제공한다. Python F-string에서 영감을 받은 형식 문자열 리터럴은 스트래포맷 모듈을 통해 제공되며, 스트래포맷 매크로에서는 형식 문자열의 형식이 양호하고 형식이 올바른지 확인한 후 컴파일 시간에 Nim 소스 코드로 확장된다.

수입하다 거드름 피우다, 스트로폼을 하다 시합을 하다 사과 = 4 시합을 하다 바나나 = 3 메아리치다 "있다. $1 사과.".형식을 갖추다(사과) 메아리치다 fmt"나는 {apples}개의 사과를 가지고 있다" 메아리치다 Fmt"나는{사과+바나나}과일들이 있습니다.".  #Multi-line 메아리치다 fmt""" I 가지고 있  {사과} 사과."""  #형식 지정 Debug 메아리치다 fmt"나는{apples=}사과가 있"  #사용자 지정 openChar과closeChar 있는 캐릭터다. 메아리치다 fmt("I have (apples) {apples}", '(', ')')  #의 서식이 지정된 문자열 리터럴 안에 Backslash. 메아리치다 fmt"""{ "네.\nope"}""" 

산출물은 다음과 같다.

나는 4{사과}yep ope다 apples=4 사과 4개의 사과 나는 4개 자기고 있어서 7의 과일 사과 4개를 가지고 있다. 

닉스

numberOfApples)"4";"나는${numberOfApples}사과가 있"게 해라. 

산출물은 다음과 같다.

4사과가 있 

파라세일

경시하다 사과 := 4 경시하다 바나나 := 3 Println ("나는 사과 `(사과)다.\n") Println ("저는 과일 `(Apples+Bananas)다.\n") 

산출물은 다음과 같다.

4사과가 있습니다. 나는 7개의 과일을 가지고 있다.  

나의 달러화 = 4; 나의 달러화 = 3; 인쇄하다 "달러 사과 사과가 있습니다.\n"; 인쇄하다 "저는{[달러 apples+$ 바나나]}과일 @다.\n";  #의 펄 배열(@)보간법을 사용합니다. 

산출물은 다음과 같다.

4사과가 있습니다. 나는 7개의 과일을 가지고 있다.  

PHP

<>?php 달러화 = 5; 달러화 = 3; 메아리치다 들이 달러화 사과와 달러화 bananas."; 메아리치다 "\n"; 메아리치다 "있다. {달러화} 사과와 {달러화} 바나나."; 

산출물은 다음과 같다.

사과 5개와 바나나가 3개 있다. 나는 5개의 사과와 3개의 바나나를 가지고 있다.  

파이톤

# 모든 버전에서 # 사과 = 4 바나나 = 3 인쇄하다("있다. %d 사과와 %d 바나나" % (사과, 바나나))  # 더 이상 추천하지 않음 인쇄하다("있다. %(수치)d 사과와 %(수치)d 바나나" % 현지인())  # 더 이상 추천하지 않음 # 파이썬 2.6+ 인쇄하다("있다. {0} 사과와 {1} 바나나".형식을 갖추다(사과, 바나나)) 인쇄하다("있다. {a} 사과와 {b} 바나나".형식을 갖추다(b=바나나, a=사과)) # Python 2.7+ 인쇄하다("있다. {} 사과와 {} 바나나".형식을 갖추다(사과, 바나나)) # 또는 Python 3.6+와 함께 인쇄하다(f"있다. {사과} 사과와 {바나나} 바나나") 

[9][10]

산출물은 다음과 같다.

나는 4개의 사과와 3개의 바나나를 가지고 있다. 

루비 / 크리스탈

사과 = 4 놓다 "있다. #{사과} 사과." # 또는 놓다 " %s 사과를 가지고 있다" % 사과 # 또는 놓다 " %{a}개의 사과를 가지고 있다" % {a: 사과} 

산출물은 다음과 같다.

나는 4개의 사과를 가지고 있다. 

진정한 보간 문자열이 부족한 러스트는 std:::fmt 모듈을 통해 해결 방법을 제공하며, 이 모듈은 포맷!, 쓰기!, 인쇄!와 같은 다양한 매크로를 통해 인터페이스된다. 이러한 매크로는 컴파일 시간에 러스트 소스 코드로 변환되며, 여기서 각 인수는 포맷터와 상호 작용한다. 포맷터는 위치 매개변수, 명명된 매개변수, 인수 유형 및 다양한 포맷 특성 정의를 지원한다.

하게 하다 (사과, 바나나) = (4, 3); 인쇄하다!("사과는 {}개, 바나나는 {}개 있어.", 사과, 바나나); 

산출물은 다음과 같다.

4개의 사과와 3개의 바나나가 있다.  

스칼라

Scala 2.10+는 s, f,raw 문자열 보간기를 구현했다. 맞춤형으로 쓰거나 표준으로 된 것을 덮어쓰는 것도 가능하다.

f 인터폴레이터는 문자열의 호출로 식이 포함된 형식 문자열을 다시 쓰는 컴파일러 매크로다.형식. 형식 문자열의 형식과 형식이 올바른지 검증한다.

표준 인터폴레이터

Scala 2.10+의 문자열 보간법은 변수 참조를 처리된 문자열 리터럴에 직접 포함시킬 수 있다. 예를 들면 다음과 같다.

발랄하게 하다 사과 = 4 발랄하게 하다 바나나 = 3 //스칼라 2.10 이전 활자화하다(" %d개 사과\n", 사과) 인쇄하다(" %d개의 사과를 가지고 있다" 형식을 갖추다 사과) //Scala 2.10 이상 인쇄하다(가지고 있다 $사과 사과.") 인쇄하다(가지고 있다 ${사과 + 바나나} 과일") 인쇄하다(f"I have $사과%d개 사과") 

산출물은 다음과 같다.

나는 4개의 사과를 가지고 있다. 

Sciter(설명서)

Sciter에서 $에서 시작하는 이름의 함수는 보간 함수로 간주되므로 보간은 사용자 정의 가능하고 상황에 민감하다.

시합을 하다 사과 = 4 시합을 하다 바나나 = 3 시합을 하다 돔먼트 = ...;  돔먼트.$content(<p>I 가지고 있 {사과} 사과</p>;; 돔먼트.달러화(<p>I 가지고 있 {사과 + 바나나} 과일들</p>;; 

어디에

돔먼트.나는 사과를 {apples}개 가지고 있다. 

다음과 같이 컴파일된다.

돔먼트.html = "가졌다. + 사과.ToHtmlString() + "사과"; 

속물

   사과 = 4 ; 바나나 = 3    출력 = "있었어." 사과 "사과."    출력 = "있었어."  (사과 + 바나나) "과일." 

산출물은 다음과 같다.

나는 사과가 4개 있다. 나는 7개의 과일을 가지고 있다.  

스위프트

Swift에서는 문자열 리터럴 내부에 해당 값을 포함시켜 상수, 변수, 리터럴 및 식을 혼합하여 새로운 문자열 값을 생성할 수 있다.[11] 문자열 리터럴에 삽입된 각 항목은 백슬래시로 접두사가 붙은 괄호 한 쌍으로 싸여 있다.

하게 하다 사과 = 4 인쇄하다("있다. \(사과)") 

산출물은 다음과 같다.

나는 4개의 사과를 가지고 있다. 

Tcl

도구 명령어는 항상 모든 따옴표로 구분된 문자열에서 문자열 보간을 지원해왔다.

세트 사과 4 "나는 $apples 사과를 가지고 있다."라고 말한다. 

산출물은 다음과 같다.

나는 사과가 4개 있다.  

단순히 값을 대체하는 것이 아니라 실제로 포맷하기 위해 포맷 기능이 있다.

set apples 4 put [형식 "%d apples." $apples] 

타이프스크립트

버전 1.4를 기준으로 TypeScript는 백틱을 사용한 문자열 보간을 지원한다. ``예를 들어,

시합을 하다 사과: 번호를 붙이다 = 4; 위로하다.통나무를 하다(가지고 있다 ${사과} 사과); 

산출물은 다음과 같다.

나는 4개의 사과를 가지고 있다. 

console.log 함수를 a로 사용할 수 있다. printf 기능을 하다 위의 예는 다음과 같이 다시 쓸 수 있다.

시합을 하다 사과: 번호를 붙이다 = 4; 위로하다.통나무를 하다(" %d개의 사과를 가지고 있다", 사과); 

생산량은 그대로다.

비주얼 베이직

Visual Basic 14의 String Interpolation은 Visual Basic에서 지원된다.[12]

이름을 붙이다 = "톰" 콘솔.WriteLine($"안녕, {name}") 

"안녕, 톰"을 인쇄할 것이다.

참고 항목

메모들

  1. ^ "템플릿 엔진에서 엄격한 모델-뷰 분리 강화", T. Parr(2004), WWW2004 컨퍼런스.
  2. ^ http://perlmeme.org/howtos/using_perl/interpolation.html
  3. ^ 자리 표시자-템플릿-시스템에 대한 온라인 자습서인 "소형-템플릿-시스템/간단한 알고리즘".
  4. ^ http://google-caja.googlecode.com/svn/changes/mikesamuel/string-interpolation-29-Jan-2008/trunk/src/js/com/google/caja/interp/index.html#-autogen-id-1 Wayback Machine에 2012-10-19 아카이브
  5. ^ https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#string-threadation
  6. ^ "The Apache Groovy programming language - Syntax". groovy-lang.org. Retrieved 2021-06-20.
  7. ^ "Haxe - Manual - String interpolation". Haxe - The Cross-platform Toolkit. Retrieved 2017-09-12.
  8. ^ https://developer.mozilla.org/docs/Web/JavaScript/Reference/Template_literals
  9. ^ https://docs.python.org/3/whatsnew/3.0.html
  10. ^ https://www.python.org/dev/peps/pep-0498/
  11. ^ "Strings and Characters — The Swift Programming Language (Swift 5.5)". docs.swift.org. Retrieved 2021-06-20.
  12. ^ KathleenDollard. "Interpolated Strings - Visual Basic". docs.microsoft.com. Retrieved 2021-06-20.