문자열

[alt=컴퓨팅에서의 문자열 데이터 다이어그램. 각 글자가 별도의 상자에 들어 있는 "example"이라는 단어를 보여준다. 단어 "String"은 문장 전체를 가리키며 위에 표시되어 있다. "Character"라는 레이블은 아래에 있으며 개별 상자를 가리킨다.|섬네일|문자열은 일반적으로 [문자 (컴퓨팅)|문자로 구성되며, 단어나 문장과 같이 사람이 읽을 수 있는 데이터를 저장하는 데 자주 사용된다.]]

컴퓨터 프로그래밍에서 **문자열**(文字列) 또는 **스트링**(string)은 전통적으로 리터럴 상수 또는 일종의 변수로서의 문자 수열을 말한다. 변수인 경우 요소가 변경되거나 길이가 변할 수 있고, (생성 후) 고정될 수도 있다. 문자열은 종종 일정한 문자 인코딩을 사용하여 요소(일반적으로 문자)의 서열을 저장하는 바이트(또는 워드)의 배열 자료 구조로 구현된다. 더 광범위하게는, 문자열은 문자뿐만 아니라 다른 데이터의 서열(또는 리스트)을 나타낼 수도 있다.

사용되는 프로그래밍 언어와 정확한 자료형에 따라, 문자열로 선언된 변수는 미리 정해진 최대 길이에 대해 메모리에 정적으로 할당되거나, 가변적인 수의 요소를 가질 수 있도록 동적 할당을 사용할 수 있다.

문자열이 소스 코드에 리터럴로 나타날 때, 이를 문자열 리터럴 또는 익명 문자열이라고 한다.

수리논리학 및 이론 컴퓨터 과학에서 사용되는 형식 언어에서 문자열은 알파벳이라고 불리는 집합에서 선택된 기호들의 유한한 수열이다.

## 용도
문자열의 주요 목적은 단어나 문장과 같이 사람이 읽을 수 있는 텍스트를 저장하는 것이다. 문자열은 컴퓨터 프로그램에서 프로그램 사용자에게 정보를 전달하는 데 사용된다. 프로그램은 사용자로부터 문자열 입력을 받을 수도 있다. 또한, 문자열은 문자로 표현되지만 사람이 읽기 위한 목적이 아닌 데이터를 저장할 수도 있다.

문자열의 예시와 그 용도:

* "`file upload complete`"와 같은 메시지는 소프트웨어가 최종 사용자에게 보여주는 문자열이다. 프로그램의 소스 코드에서 이 메시지는 문자열 리터럴로 나타날 가능성이 높다.
* 소셜 미디어 서비스에서 상태 업데이트로 입력된 "`I got a new job today`"와 같은 사용자 입력 텍스트. 소프트웨어는 이를 문자열 리터럴 대신 데이터베이스에 저장할 것이다.
* DNA의 핵산 서열을 나타내는 "`AGATGCCGT`"와 같은 알파벳 데이터.
* URL 쿼리 문자열인 "`?action=edit`"과 같은 컴퓨터 설정 또는 매개변수. 이는 종종 어느 정도 사람이 읽을 수 있도록 의도되지만, 주요 목적은 컴퓨터 간의 통신이다.

문자열이라는 용어는 "비트 문자열"과 같이 문자 이외의 데이터나 컴퓨터 레코드의 서열을 지칭할 수도 있지만, 별도의 수식어 없이 사용될 때는 문자의 문자열을 의미한다.

## 역사
한 줄, 일련의 순서 또는 연속으로 배열된 항목을 의미하기 위해 "문자열"(string)이라는 단어를 사용한 것은 수 세기 전으로 거슬러 올라간다. 19세기 조판에서 식자공들은 종이에 인쇄된 활자의 길이를 나타내기 위해 "문자열"이라는 용어를 사용했으며, 이 문자열을 측정하여 식자공의 임금을 결정했다.

"확정된 순서의 기호 또는 언어적 요소의 서열"을 의미하는 "문자열"이라는 단어의 사용은 수학, 기호 논리학, 언어학 이론에서 기호의 의미를 배제하고 기호 체계의 형식적 행동을 다루기 위해 등장했다.

예를 들어, 논리학자 C. I. 루이스는 1918년에 다음과 같이 썼다.

수학 체계는 인식 가능한 표식들의 문자열들의 집합이며, 그 중 일부 문자열은 초기에 취해지고 나머지는 표식에 할당된 의미와 무관한 규칙에 따라 수행되는 연산에 의해 이들로부터 도출된다. 체계가 소리나 냄새 대신 '표식'으로 구성되어야 한다는 점은 중요하지 않다.


진 E. 새밋에 따르면, 컴퓨터를 위한 "최초의 현실적인 문자열 처리 및 패턴 매칭 언어"는 1950년대의 COMIT였으며, 그 뒤를 이어 1960년대 초의 SNOBOL 언어가 등장했다.

## 문자열 자료형

**문자열 자료형**은 형식 문자열의 개념을 모델로 한 자료형이다. 문자열은 매우 중요하고 유용한 자료형이어서 거의 모든 프로그래밍 언어에 구현되어 있다. 일부 언어에서는 원시 자료형으로 제공되고 다른 언어에서는 복합 자료형으로 제공된다. 대부분의 고수준 프로그래밍 언어의 통사론은 일반적으로 일정한 방식으로 따옴표가 붙은 문자열이 문자열 자료형의 인스턴스를 나타낼 수 있도록 허용하며, 이러한 메타 문자열을 리터럴 또는 문자열 리터럴이라고 한다.

### 문자열 길이
형식 문자열은 임의의 유한한 길이를 가질 수 있지만, 실제 언어에서의 문자열 길이는 종종 인위적인 최대값으로 제한된다. 일반적으로 두 가지 유형의 문자열 자료형이 있다. 고정 길이 문자열은 컴파일 타임에 결정되는 고정된 최대 길이를 가지며, 이 최대값이 필요한지 여부에 관계없이 동일한 양의 메모리를 사용한다. 가변 길이 문자열은 길이가 임의로 고정되지 않으며 런타임 시 실제 요구 사항에 따라 가변적인 양의 메모리를 사용할 수 있다(메모리 관리 참조). 현대 프로그래밍 언어의 대부분의 문자열은 가변 길이 문자열이다. 물론 가변 길이 문자열이라 하더라도 가용한 메모리 양에 의해 길이는 제한된다. 문자열 길이는 별도의 정수(이 또한 길이에 인위적인 제한을 둘 수 있음)로 저장되거나, C 프로그래밍 언어에서처럼 모든 비트가 0인 문자 값과 같은 종단 문자를 통해 암시적으로 저장될 수 있다. 아래의 "널 종단" 부분도 참조하라.

### 문자 인코딩
문자열 자료형은 역사적으로 문자당 1바이트를 할당해 왔으며, 정확한 문자 집합은 지역마다 달랐지만, 프로그램이 특별히 취급하는 문자(마침표, 공백, 쉼표 등)가 모든 인코딩에서 동일한 위치에 있었기 때문에 프로그래머들은 종종 이를 무시하고 넘어갈 수 있었다. 이러한 문자 집합은 대개 ASCII 또는 EBCDIC에 기반했다. 한 인코딩으로 된 텍스트가 다른 인코딩을 사용하는 시스템에서 표시되면 텍스트가 종종 깨졌지만, 어느 정도 읽을 수 있는 경우도 있었고 일부 컴퓨터 사용자들은 깨진 텍스트를 읽는 법을 배우기도 했다.

중국어, 일본어, 한국어(통칭 CJK)와 같은 표의 문자 언어는 합리적인 표현을 위해 256개 이상의 문자(8비트 1바이트 문자당 인코딩의 한계)가 필요하다. 일반적인 해결책은 ASCII에 대해서는 싱글 바이트 표현을 유지하고 CJK 표의 문자에 대해서는 2바이트 표현을 사용하는 것이었다. 이를 기존 코드와 함께 사용하면 문자열의 매칭 및 절단에 문제가 발생했으며, 그 심각성은 문자 인코딩이 어떻게 설계되었느냐에 따라 달랐다. EUC 계열과 같은 일부 인코딩은 ASCII 범위의 바이트 값이 해당 ASCII 문자만을 나타내도록 보장하여, 해당 문자를 필드 구분자로 사용하는 시스템에서 인코딩이 안전하도록 만들었다. ISO-2022 및 Shift-JIS와 같은 다른 인코딩은 이러한 보장을 하지 않아 바이트 코드에 기반한 매칭이 안전하지 않게 되었다. 이러한 인코딩은 또한 "자기 동기화"가 되지 않아 문자 경계를 찾기 위해 문자열 시작 부분까지 거슬러 올라가야 했으며, 두 문자열을 합치면 두 번째 문자열이 손상될 수 있었다.

유니코드는 이 상황을 다소 단순화했다. 현재 대부분의 프로그래밍 언어는 유니코드 문자열을 위한 자료형을 가지고 있다. 유니코드가 선호하는 바이트 스트림 형식인 UTF-8은 이전의 멀티바이트 인코딩에서 설명한 문제들을 겪지 않도록 설계되었다. UTF-8, UTF-16 및 UTF-32는 프로그래머가 고정된 크기의 코드 유닛이 "문자"와 다르다는 점을 알아야 하며, 현재 주요 어려움은 이러한 차이를 숨기려 하는 잘못 설계된 API들이다(UTF-32는 코드 포인트를 고정된 크기로 만들지만, 조합 코드 때문에 이것들이 곧 "문자"인 것은 아니다).

### 구현
C++, 펄, 루비와 같은 일부 언어는 일반적으로 문자열이 생성된 후에 그 내용을 변경할 수 있도록 허용하며, 이를 가변(mutable) 문자열이라고 한다. 자바, 자바스크립트, 루아, 파이썬, Go와 같은 다른 언어에서는 값이 고정되며 변경이 필요한 경우 새 문자열을 생성해야 하는데, 이를 불변(immutable) 문자열이라고 한다. 불변 문자열을 사용하는 이러한 언어들 중 일부는 자바 및 닷넷의 , 스레드에 안전한 자바 , 코코아의 `NSMutableString`과 같이 가변적인 다른 유형을 제공하기도 한다. 불변성은 장단점을 가진다. 불변 문자열은 비효율적으로 많은 사본을 생성해야 할 수도 있지만, 더 단순하고 완전히 스레드 안전하다.

문자열은 일반적으로 개별 유닛이나 서브스트링에 빠르게 접근할 수 있도록 바이트, 문자 또는 코드 유닛의 배열로 구현된다. 하스켈과 같은 몇몇 언어는 대신 이를 연결 리스트로 구현한다.

많은 고수준 언어는 자바스크립트나 PHP처럼 문자열을 원시 자료형으로 제공하는 반면, 자바나 C#과 같은 다른 언어들은 복합 자료형으로 제공하며 리터럴을 작성할 때 특별한 언어적 지원을 제공한다.

C, 프롤로그, 얼랭과 같은 일부 언어는 전용 문자열 자료형의 구현을 아예 피하고, 대신 문자 코드의 리스트로 문자열을 표현하는 관습을 채택한다. 전용 문자열 유형이 있는 프로그래밍 언어에서도 문자열은 보통 정수 리스트나 다른 값들처럼 문자 코드의 시퀀스로 반복(iterate)될 수 있다.

### 표현 방식
문자열의 표현은 문자 레퍼토리의 선택과 문자 인코딩 방식에 크게 좌우된다. 과거의 문자열 구현은 ASCII 또는 ISO 8859 시리즈와 같은 최신 확장에 의해 정의된 레퍼토리와 인코딩에서 작동하도록 설계되었다. 현대의 구현은 종종 UTF-8 및 UTF-16과 같은 다양한 복잡한 인코딩과 함께 유니코드에 의해 정의된 광범위한 레퍼토리를 사용한다.

바이트 문자열이라는 용어는 보통 (읽기 가능한) 문자의 문자열이나 비트 문자열 등이 아니라, 범용적인 바이트의 문자열을 의미한다. 바이트 문자열은 종종 바이트가 어떤 값도 가질 수 있고 어떤 데이터든 있는 그대로 저장될 수 있음을 시사하며, 이는 종단 값으로 해석되는 값이 없어야 함을 의미한다.

대부분의 문자열 구현은 항목에 해당 문자의 문자 코드를 저장하는 가변 길이 배열과 매우 유사하다. 주요 차이점은 특정 인코딩의 경우 하나의 논리적 문자가 배열에서 둘 이상의 항목을 차지할 수 있다는 것이다. 이는 예를 들어 UTF-8에서 발생하는데, 단일 코드(UCS 코드 포인트)는 1바이트에서 4바이트 사이의 어디든 차지할 수 있고, 단일 문자는 임의의 개수의 코드를 차지할 수 있다. 이러한 경우 문자열의 논리적 길이(문자 수)는 배열의 물리적 길이(사용 중인 바이트 수)와 다르다. UTF-32는 문제의 첫 번째 부분을 피한다.

#### 도프 벡터
문자열의 길이는 실제 문자가 저장된 공간과 분리된 도프 벡터(dope vector)에 저장될 수 있다. IBM PL/I (F) 컴파일러는 가변 길이 문자열과 문자열 매개변수 전달을 위해 **문자열 도프 벡터** (SDV)를 사용했다. SDV는 현재 길이와 최대 길이를 포함하며, 실제 문자열에 인접해 있지 않다. PL/I (F) 이후 IBM은 SDV를 버리고 길이 접두사 방식의 문자열을 선호하게 되었다.

#### 널 종단

특별한 종단 문자를 사용하여 문자열의 길이를 암시적으로 저장할 수 있다. 종종 이는 모든 비트가 0인 널 문자(NUL)이며, 이는 대중적인 C 프로그래밍 언어에 의해 사용되고 영속화된 관습이다. 따라서 이 표현 방식은 일반적으로 **C 문자열**이라고 불린다. n개의 문자로 구성된 문자열의 이 표현 방식은 n + 1의 공간(1은 종단 문자용)을 차지하며, 따라서 암시적 자료 구조이다.

종단된 문자열에서 종단 코드는 어떠한 문자열에서도 허용되는 문자가 아니다. 길이 필드가 있는 문자열은 이러한 제한이 없으며 임의의 이진 데이터도 저장할 수 있다.

10바이트 버퍼에 저장된 널 종단 문자열과 8비트 십육진법 숫자로 된 ASCII(또는 현대적인 UTF-8) 표현의 예시는 다음과 같다.

위의 예에서 "`FRANK`" 문자열의 길이는 5자이지만 6바이트를 차지한다. 종단 문자 이후의 문자들은 표현의 일부가 아니며, 다른 데이터의 일부이거나 단지 쓰레기 데이터(garbage)일 수 있다. (이러한 형식의 문자열은 이를 선언하는 데 사용된 원래의 어셈블리어 지시어의 이름을 따서 종종 ASCIZ 문자열이라고 불린다.)

#### 바이트 및 비트 종단
문자열을 종단하기 위해 널 이외의 특별한 바이트를 사용하는 방식은 역사적으로 하드웨어와 소프트웨어 모두에서 나타났으며, 때로는 출력 가능한 문자 값을 사용하기도 했다. `$`는 많은 어셈블러 시스템에서 사용되었고, `:`는 CDC 시스템에서 사용되었으며(이 문자는 0의 값을 가졌음), ZX80은 자신의 BASIC 언어에서 문자열 구분자였기 때문에 `"`를 사용했다.

이와 다소 유사하게, IBM 1401과 같은 "데이터 처리" 기계는 연산이 오른쪽에서 시작되는 경우 왼쪽에서 문자열을 구분하기 위해 특별한 워드 마크 비트를 사용했다. 이 비트는 문자열의 다른 모든 부분에서는 해제되어야 했다. 이는 IBM 1401이 7비트 워드를 가졌음에도 불구하고, 거의 아무도 이를 기능으로 사용하여 (예를 들어) ASCII 코드를 처리하기 위해 일곱 번째 비트의 할당을 무시하려 하지 않았음을 의미했다.

초기 마이크로컴퓨터 소프트웨어는 ASCII 코드가 상위 비트를 사용하지 않는다는 사실에 의존하여, 상위 비트를 문자열의 끝을 나타내도록 설정했다. 출력 전에는 이를 0으로 리셋해야 했다.

#### 길이 접두사
문자열의 길이는 명시적으로 저장될 수도 있는데, 예를 들어 바이트 값으로 문자열 앞에 길이를 접두사로 붙이는 방식이다. 이 관습은 많은 파스칼 방언에서 사용되며, 그 결과 사람들은 이러한 문자열을 **파스칼 문자열** 또는 **P-문자열**이라고 부른다. 문자열 길이를 바이트로 저장하면 최대 문자열 길이가 255로 제한된다. 이러한 제한을 피하기 위해 P-문자열의 개선된 구현은 문자열 길이를 저장하기 위해 16, 32 또는 64비트 워드를 사용한다. 길이 필드가 주소 공간을 커버할 때, 문자열은 가용한 메모리에 의해서만 제한된다.

길이가 유한하다면 상수 공간(일반적으로 머신 워드)에 인코딩될 수 있으며, 이는 n + k 공간을 차지하는 암시적 자료 구조로 이어진다. 여기서 k는 워드 내의 문자 수이다(64비트 기계의 8비트 ASCII의 경우 8, 32비트 기계의 32비트 UTF-32/UCS-4의 경우 1 등).
길이가 제한되지 않는 경우, 길이 n을 인코딩하는 데 log(n) 공간이 소요되므로 길이 접두사 문자열은 길이 n의 문자열을 log(n) + n 공간에 인코딩하는 간결한 자료 구조(succinct data structure)이다.

후자의 경우, 길이 접두사 필드 자체의 길이가 고정되어 있지 않으므로 문자열이 커져서 길이 필드를 늘려야 할 때 실제 문자열 데이터를 이동시켜야 한다.

다음은 10바이트 버퍼에 저장된 파스칼 문자열과 그 ASCII / UTF-8 표현이다.

#### 레코드로서의 문자열
객체 지향 언어를 포함한 많은 언어는 다음과 같은 내부 구조를 가진 레코드로 문자열을 구현한다.


```cpp
public final class String {
    private unsigned long length; // 문자열 길이
    private UniquePointer<char[]> text; // 명시적 소유권

    // 공개 메서드...
}
```


그러나 구현이 대개 정보 은닉되어 있으므로 멤버 함수를 통해 문자열에 접근하고 수정해야 한다. `text`는 필요에 따라 확장될 수 있는 동적으로 할당된 메모리 영역에 대한 포인터이다. C++ 문자열도 참조하라.

#### 기타 표현 방식
문자 종단과 길이 코드 모두 문자열을 제한한다. 예를 들어, 널(NUL) 문자를 포함하는 C 문자 배열은 C 문자열 처리 라이브러리 함수에 의해 직접 처리될 수 없다. 길이 코드를 사용하는 문자열은 길이 코드의 최대값으로 제한된다.

영리한 프로그래밍을 통해 이 두 가지 제한을 모두 극복할 수 있다.

문자 종단과 관련된 문제가 없고 원칙적으로 길이 코드 한계를 극복할 수 있는 자료 구조와 이를 조작하는 함수를 만드는 것이 가능하다. 또한 런 렝스 부호화(반복되는 문자를 문자 값과 길이로 대체) 및 해밍 부호화 기술을 사용하여 표현된 문자열을 최적화하는 것도 가능하다.

이러한 표현 방식이 일반적이지만 다른 방식도 가능하다. 로프(rope)를 사용하면 삽입, 삭제 및 연결과 같은 특정 문자열 연산을 더 효율적으로 만들 수 있다.

문서 편집기의 핵심 자료 구조는 편집 중인 파일의 현재 상태를 나타내는 문자열(문자 서열)을 관리하는 것이다.
해당 상태는 하나의 긴 연속된 문자 배열에 저장될 수 있지만, 전형적인 문서 편집기는 대신 갭 버퍼, 행의 연결 리스트, 피스 테이블(piece table) 또는 로프와 같은 대체 표현을 시퀀스 자료 구조로 사용하며, 이는 삽입, 삭제 및 이전 편집 취소와 같은 특정 문자열 연산을 더 효율적으로 만든다.

### 보안 문제
문자열의 서로 다른 메모리 배치 및 저장 요구 사항은 문자열 데이터에 접근하는 프로그램의 보안에 영향을 미칠 수 있다. 종단 문자가 필요한 문자열 표현은 코딩 오류나 공격자가 의도적으로 데이터를 변경하여 종단 문자가 존재하지 않는 경우 버퍼 오버플로 문제에 취약하다. 별도의 길이 필드를 채택하는 문자열 표현 또한 길이를 조작할 수 있는 경우 취약할 수 있다. 이러한 경우 문자열 데이터에 접근하는 프로그램 코드는 문자열 메모리 한계를 벗어난 데이터에 부주의하게 접근하거나 변경하지 않도록 경계 검사가 필요하다.

문자열 데이터는 종종 프로그램에 대한 사용자 입력으로부터 얻어진다. 따라서 문자열이 예상된 형식을 나타내는지 검증하는 것은 프로그램의 책임이다. 사용자 입력에 대해 제한적이거나 전혀 검증을 수행하지 않는 것은 프로그램이 코드 인젝션 공격에 취약해지게 만들 수 있다.

## 리터럴 문자열

때때로 문자열은 사람이 읽을 수 있고 기계가 소비하도록 의도된 텍스트 파일 내에 포함되어야 한다. 이는 예를 들어 프로그래밍 언어의 소스 코드나 설정 파일에서 필요하다. 이 경우 NUL 문자는 일반적으로 보이지 않고(인쇄되지 않음) 키보드를 통해 입력하기 어렵기 때문에 종단 문자로 잘 작동하지 않는다. 수동으로 길이를 계산하고 추적하는 것은 지루하고 오류가 발생하기 쉽기 때문에 문자열 길이를 저장하는 것도 불편할 것이다.

두 가지 일반적인 표현 방식은 다음과 같다.
* 대부분의 프로그래밍 언어에서 사용되는 따옴표로 둘러싸인 방식(ASCII 0x22 큰따옴표 `"str"` 또는 ASCII 0x27 작은따옴표 `'str'`). 따옴표 자체, 새줄 문자 또는 인쇄되지 않는 문자와 같은 특수 문자를 포함할 수 있도록 대개 역슬래시 문자(ASCII 0x5C)가 앞에 붙는 이스케이프 시퀀스가 제공된다.
* 예를 들어 윈도우 INI 파일에서와 같이 새줄 문자 서열에 의해 종단되는 방식.

## 비텍스트 문자열
문자열의 매우 일반적인 용도는 문자 문자열이지만, 컴퓨터 과학에서 문자열은 동질적으로 유형화된 데이터의 모든 서열을 포괄적으로 지칭할 수 있다. 예를 들어, 통신 매체로부터 검색된 텍스트가 아닌 이진 데이터를 표현하기 위해 비트 문자열이나 바이트 문자열이 사용될 수 있다. 이 데이터는 애플리케이션의 필요, 프로그래머의 의도, 사용 중인 프로그래밍 언어의 능력에 따라 문자열 전용 자료형으로 표현될 수도 있고 그렇지 않을 수도 있다. 프로그래밍 언어의 문자열 구현이 8비트 클린(8-bit clean)하지 않다면 데이터 손상이 발생할 수 있다.

C 프로그래머들은 정의상 항상 널로 종단되는 "문자열"(문자의 문자열)과, 동일한 배열에 저장될 수 있지만 종종 널로 종단되지 않는 "문자 배열"을 엄격하게 구분한다.
이러한 문자 배열에 C 문자열 처리 함수를 사용하는 것은 종종 작동하는 것처럼 보이지만 나중에 보안 문제로 이어진다.

## 문자열 처리 알고리즘
문자열 처리를 위한 많은 알고리즘이 있으며, 각각 다양한 절충점이 있다. 경쟁하는 알고리즘들은 실행 시간, 저장 공간 요구 사항 등에 대해 알고리즘 분석을 할 수 있다. **스트링올로지**(stringology)라는 이름은 1984년 컴퓨터 과학자 즈비 갈릴이 문자열 처리에 사용되는 알고리즘과 자료 구조의 이론을 위해 만든 용어이다.

알고리즘의 일부 범주는 다음과 같다.
* 주어진 서브스트링이나 패턴을 찾기 위한 문자열 검색 알고리즘
* 문자열 조작 알고리즘
* 정렬 알고리즘
* 정규 표현식 알고리즘
* 문자열 구문 분석
* 시퀀스 마이닝(sequence mining)

고급 문자열 알고리즘은 종종 접미사 트리와 유한 상태 기계를 포함한 복잡한 메커니즘과 자료 구조를 사용한다.

## 문자열 지향 언어 및 유틸리티
문자열은 매우 유용한 자료형이어서 문자열 처리 애플리케이션을 쉽게 작성할 수 있도록 여러 언어가 설계되었다. 예시는 다음과 같은 언어들을 포함한다.
* AWK
* 아이콘
* MUMPS
* 펄
* REXX
* 루비
* sed
* SNOBOL
* Tcl
* TTM

많은 유닉스 유틸리티는 간단한 문자열 조작을 수행하며 강력한 문자열 처리 알고리즘을 쉽게 프로그래밍하는 데 사용될 수 있다. 파일과 유한한 스트림은 문자열로 간주될 수 있다.

멀티미디어 컨트롤 인터페이스, 임베디드 SQL 또는 Printf와 같은 일부 API는 해석될 명령을 보관하기 위해 문자열을 사용한다.

펄, 파이썬, 루비, Tcl을 포함한 많은 스크립팅 언어는 텍스트 연산을 용이하게 하기 위해 정규 표현식을 사용한다. 펄은 특히 정규 표현식 사용으로 유명하며, 다른 많은 언어와 애플리케이션이 펄 호환 정규 표현식을 구현한다.

펄과 루비 같은 일부 언어는 문자열 리터럴 내에 임의의 식이 평가되고 포함될 수 있도록 하는 문자열 보간(string interpolation)을 지원한다.

## 문자열 함수

문자열 함수는 문자열을 생성하거나 가변 문자열의 내용을 변경하는 데 사용된다. 또한 문자열에 대한 정보를 쿼리하는 데에도 사용된다. 함수의 집합과 그 이름은 프로그래밍 언어에 따라 다르다.

문자열 함수의 가장 기본적인 예는 문자열 길이 함수로, 문자열의 길이를 반환하고(종단 문자나 문자열의 내부 구조 정보는 제외) 문자열을 수정하지 않는 함수이다. 이 함수는 종종 `[[comparison of programming languages (string functions)#length |length]]`, `len` 또는 `size`라고 명명된다. 예를 들어, `length("hello world")`는 11을 반환한다. 또 다른 공통적인 함수는 문자열 연결로, 두 문자열을 덧붙여 새 문자열을 생성하며 종종 + 더하기 연산자가 사용된다.

일부 마이크로프로세서의 명령어 집합 아키텍처는 블록 복사와 같은 문자열 연산을 직접 지원한다(예: 인텔 x86의 `REPNZ MOVSB`).

## 형식 이론

\Sigma를 알파벳이라고 불리는 뚜렷하고 모호하지 않은 기호(또는 문자)들의 유한 집합이라고 하자. \Sigma에 대한 **문자열**(또는 **단어** 또는 **표현식**)은 \Sigma에서 가져온 기호들의 임의의 유한한 수열이다. 예를 들어, \Sigma = \{\texttt{0}, \texttt{1}\}이라면 \texttt{01011}은 \Sigma에 대한 문자열이다.

문자열 s의 길이는 s에 포함된 기호의 개수(수열의 길이)이며 임의의 비음의 정수가 될 수 있다. 이는 종종 |s|로 표기된다. 빈 문자열은 길이가 0인 \Sigma 위의 유일한 문자열이며, \varepsilon 또는 \lambda로 표기된다.

길이가 n인 \Sigma 위의 모든 문자열의 집합은 \Sigma^n으로 표기된다. 예를 들어, \Sigma = \{\texttt{0}, \texttt{1}\}이라면 \Sigma^2 = \{\texttt{00}, \texttt{01}, \texttt{10}, \texttt{11}\}이다. 모든 알파벳 \Sigma에 대해 \Sigma^0 = \{\varepsilon\}이다.

임의의 길이를 가진 \Sigma 위의 모든 문자열의 집합은 \Sigma의 클레이니 폐쇄이며 \Sigma^*로 표기된다. \Sigma^n의 관점에서,
:\Sigma^{*} = \bigcup_{n = 0}^\infty \Sigma^{n}
예를 들어, \Sigma = \{\texttt{0}, \texttt{1}\}이라면 \Sigma^* = \{\varepsilon, \texttt{0}, \texttt{1}, \texttt{00}, \texttt{01}, \texttt{10}, \texttt{11}, \texttt{000}, \texttt{001}, \texttt{010}, \texttt{011}, ...\}이다. 집합 \Sigma^* 자체는 가산 무한이지만, \Sigma^*의 각 원소는 유한한 길이의 문자열이다.

\Sigma 위의 문자열들의 집합(즉, \Sigma^*의 임의의 부분집합)을 \Sigma 위의 형식 언어라고 한다. 예를 들어, \Sigma = \{\texttt{0}, \texttt{1}\}인 경우, 0의 개수가 짝수인 문자열의 집합 \{\varepsilon, \texttt{1}, \texttt{00}, \texttt{11}, \texttt{001}, \texttt{010}, \texttt{100}, \texttt{111}, \texttt{0000}, \texttt{0011}, \texttt{0101}, \texttt{0110}, \texttt{1001}, \texttt{1010}, \texttt{1100}, \texttt{1111}, ...\}은 \Sigma 위의 형식 언어이다.

### 연결 및 서브스트링
연결(Concatenation)은 \Sigma^* 위의 중요한 이항 연산이다. \Sigma^*에 속한 임의의 두 문자열 s와 t에 대해, 그들의 연결은 s의 기호 서열 다음에 t의 문자 서열이 오는 것으로 정의되며 st로 표기된다. 예를 들어, \Sigma = \{\texttt{a}, \texttt{b}, ..., \texttt{z}\}(즉, 소문자 영어 알파벳)이고 s = \texttt{bear}, t = \texttt{hug}라면 st = \texttt{bearhug}이고 ts = \texttt{hugbear}이다.

문자열 연결은 결합적이지만 교환적이지 않은 연산이다. 빈 문자열 \varepsilon은 항등원 역할을 한다. 즉, 임의의 문자열 s에 대해 \varepsilon s = s \varepsilon = s이다. 따라서 집합 \Sigma^*와 연결 연산은 \Sigma에 의해 생성된 자유 모노이드인 모노이드를 형성한다. 또한 길이 함수는 \Sigma^*에서 비음의 정수로의 모노이드 준동형 사상을 정의한다(즉, L: \Sigma^{*} \mapsto \mathbb{N} \cup \{0\}인 함수로서, L(st)=L(s)+L(t)\quad \forall s,t\in\Sigma^*를 만족한다).

문자열 t = usv가 되는 (비어 있을 수 있는) 문자열 u와 v가 존재할 때, 문자열 s를 t의 서브스트링 또는 인자(factor)라고 한다. "가 ~의 서브스트링이다"라는 이항 관계는 \Sigma^* 위에 부분 순서를 정의하며, 그 최소 원소는 빈 문자열이다.

### 접두사 및 접미사
t = su가 되는 문자열 u가 존재할 때, 문자열 s를 t의 접두사(prefix)라고 한다. 만약 u가 비어 있지 않다면 s를 t의 진접두사(proper prefix)라고 한다. 대칭적으로, t = us가 되는 문자열 u가 존재할 때, 문자열 s를 t의 접미사(suffix)라고 한다. 만약 u가 비어 있지 않다면 s를 t의 진접미사(proper suffix)라고 한다. 접미사와 접두사는 t의 서브스트링이다. "가 ~의 접두사이다"와 "가 ~의 접미사이다"라는 두 관계는 모두 접두사 순서이다.

### 반전
문자열의 반전(reversal)은 동일한 기호들을 가지지만 순서가 반대인 문자열이다. 예를 들어, s = \texttt{abc}(여기서 \texttt{a}, \texttt{b}, \texttt{c}는 알파벳의 기호)라면 s의 반전은 \texttt{cba}이다. 자기 자신과 반전이 같은 문자열(예: s = \texttt{madam})을 회문(palindrome)이라고 하며, 빈 문자열과 길이가 1인 모든 문자열도 여기에 포함된다.

### 회전
t = vu일 때 문자열 s = uv를 t의 회전(rotation)이라고 한다. 예를 들어, \Sigma = \{\texttt{0}, \texttt{1}\}일 때 문자열 \texttt{0011001}은 \texttt{0100110}의 회전이며, 여기서 u = \texttt{00110}이고 v = \texttt{01}이다. 다른 예로, 문자열 \texttt{abc}는 세 가지 서로 다른 회전을 가진다. 즉, \texttt{abc} 자신(u=\texttt{abc}, v=\varepsilon), \texttt{bca}(u=\texttt{bc}, v=\texttt{a}), 그리고 \texttt{cab}(u=\texttt{c}, v=\texttt{ab})이다.

### 사전식 순서
문자열 집합 위에 순서를 정의하는 것이 유용한 경우가 많다. 알파벳 \Sigma가 전순서를 가지면(cf. 음소문자의 순서), 사전식 순서라고 불리는 \Sigma^* 위의 전순서를 정의할 수 있다. 알파벳 순서가 전순서라면 사전식 순서도 전순서이지만, 알파벳 순서가 전순서라 하더라도 비자명한 알파벳에 대해서는 웰 파운디드(well-founded)가 아니다. 예를 들어, \Sigma = \{\texttt{0}, \texttt{1}\}이고 \texttt{0} 이라면, \Sigma^* 위의 사전식 순서는 다음과 같은 관계를 포함한다. \varepsilon  이 순서에 관해, 예를 들어 무한 집합 \{ \texttt{1}, \texttt{01}, \texttt{001}, \texttt{0001}, \texttt{00001}, \texttt{000001}, ... \}은 최소 원소를 가지지 않는다.

웰 파운디드 특성을 보존하는 대안적인 문자열 순서에 대해서는 Shortlex를 참조하라.
위 예시 알파벳의 경우, shortlex 순서는 다음과 같다. \varepsilon 

### 문자열 연산
형식 이론에서는 문자열에 대한 다수의 추가 연산이 흔히 발생한다. 이는 문자열 연산 문서에 기술되어 있다.

### 위상
[섬네일|150px|길이가 <math>3</math>인 [이진 데이터|이진 문자열의 (초)입방체]]
문자열은 그래프의 노드로 다음과 같이 해석될 수 있다. 여기서 k는 \Sigma의 기호 수이다.
* 길이가 n인 고정 길이 문자열은 변의 길이가 k-1인 n차원 초입방체의 정수 위치로 볼 수 있다.
* (유한한 길이의) 가변 길이 문자열은 완전 <math>k</math>진 트리 위의 노드로 볼 수 있다.
* 무한 문자열(여기서는 별도로 고려하지 않음)은 k개의 노드를 가진 완전 그래프 위의 무한한 경로로 볼 수 있다.

고정 길이 문자열이나 가변 길이 문자열 집합 위의 자연스러운 위상은 이산 위상이지만, 무한 문자열 집합 위의 자연스러운 위상은 무한 문자열의 집합을 유한 문자열 집합의 사영 극한으로 보는 극한 위상이다. 이것이 p-진수를 위해 사용되는 구성이며 칸토어 집합의 일부 구성 방식과 동일한 위상을 생성한다.

위상의 문자열 표현 사이의 동형 사상은 사전식 최소 문자열 회전에 따라 정규화함으로써 찾을 수 있다.

## 같이 보기
* C 문자열

## 각주

; 내용주



분류:문자 인코딩
분류:자료 구조
분류:자료형
분류:형식 언어
분류:원시 자료형
분류:문장 성분
분류:문자열 알고리즘