문자열을 자르는 함수에 대해서 정리해보자

프로그래밍 언어마다 문자열을 자르는 함수의 사용방법이 조금씩 다른경우가 많다.

string 의 멤버 함수로 substring()과 split() 두가지가 가장 흔하게 쓰이는 방식이다.

 

첫번째로 substring() 함수는 시작지점과 끝지점을 파라미터로 전달받아서 문자열을 자르게 된다.

substring(시작지점, 끝지점) 이런식으로 사용하면 된다. 

아래이미지를 보도록 하자.

 

 

substring(1, 3) 을 입력하면 인덱스가 1부터 3까지의 글자를 자르게 되는데 B부터 C까지 잘라서 "BC"가 리턴이 된다.

substring(5) 를 입력하면 인덱스 5부터 문자열 끝까지 잘라서 "3de"가 리턴된다.

 

아래 사용 예제를 보도록 하자.

public static void main(String[] args) {		
	String str = "abcdefg12345";
	System.out.println("substring(5) : " + str.substring(5));
	System.out.println("substring(0,1) : " + str.substring(0,1));
	System.out.println("substring(1,2) : " + str.substring(1,2));
	System.out.println("substring(2,3) : " + str.substring(2,3));
	System.out.println("substring(2,10) : " + str.substring(2,10));
}

출력 :

substring(5) : fg12345
substring(0,1) : a
substring(1,2) : b
substring(2,3) : c
substring(2,10) : cdefg123

 

 

만약 문자열 끝에서부터 3글자만 출력하고 싶다면 아래 예제와 같이 사용하면 된다.

public static void main(String[] args) {		
	String str = "abc123def";
	System.out.println(str.substring(str.length()-3, str.length()));
}

출력 :

def

 

그리고 아래예제와 같이 indexOf() 함수를 사용하면 특정 글자 두개를 포함하여 그사이에 글자를 모두 출력하게 된다.

 

public static void main(String[] args) {		
	String str = "abc123def";
    System.out.println(str.substring(str.indexOf("1"), str.indexOf("3") + 1));
}

출력 :

123

 

그런데 substring() 함수를 사용하다가 문자열의 길이보다 긴 값을 substring의 인자로 전달하게 되면 아래 예제와 같이 StringIndexOutOfBoundsException 에러가 발생하게 된다. 총 글자수는 12개이지만 10부터 20을 출력하라고 했기때문에 에러가 발생하였다.

 

public static void main(String[] args) {		
	String str = "abcdefg12345";
	System.out.println("substring(10,20) : " + str.substring(10,20));
}

에러 메시지 :

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: Range [10, 20) out of bounds for length 12
at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:55)
at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:52)
at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:213)
at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:210)
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:98)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckFromToIndex(Preconditions.java:112)
at java.base/jdk.internal.util.Preconditions.checkFromToIndex(Preconditions.java:349)
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4589)
at java.base/java.lang.String.substring(String.java:2703)
at TestSubString.main(TestSubString.java:5)

 

 

 

이것을 방지하기 위해서는 아래예제와 같이 StringIndexOutOfBoundsException 에러를 예외처리해주면 된다.

 

public static void main(String[] args) {		
	String str = "abcdefg12345";
	try {
		System.out.println("substring(10,20) : " + str.substring(10,20));
	} catch(StringIndexOutOfBoundsException e) {
		System.out.println("Error : "+e.getMessage());
	}		
}

출력 : 

Error : Range [10, 20) out of bounds for length 12

 


 

두번째로 split() 함수는 특정 문자열을 파라미터로 받아서 해당 문자열을 기준으로 문자열을 잘라서 배열에 넣어주는 기능을 한다. String 의 멤버함수이다. 

 

아래이미지를 보면 이해하기 쉬울 것이다.

 

 

위에 이미지를 아래는 코드화 한것이다.

 

public static void main(String[] args) {		
	String str = "ABC,EE,QQ1,5112";
	String arr[] = str.split(",");
	for(String cut : arr) {
		System.out.println(cut);
	}		
}

출력 :

ABC
EE
QQ1
5112

 

 

Posted by 꿈만은공돌
,

String 클래스의 경우 sealed 선언이 되어 있어 상속이 불가능하다.


selaed 키워드에 대해선 아래 링크 참고하자.


- C# 상속금지 키워드 sealed 키워드 : http://hijuworld.tistory.com/44


그래서 String 클래스를 상속받아 새로운 메서드를 추가하여 사용하고 싶어도 불가능하다.

아래 처럼 에러가 발생한다.




하지만 C# 3.0에서 확장 메서드 기능을 사용하면 String에 메서드를 추가한 것 같이 사용이 가능하다.


아래 코드를 보자.


1
2
3
4
5
6
7
8
9
10
using System.Text.RegularExpressions;
 
static class PlusString
{
    public static bool IsValidPhone(this string input)
    {
        Regex regex = new Regex(@"^01[01678]-[0-9]{4}-[0-9]{4}$");
        return regex.IsMatch(input);
    }
}
cs




static으로 선언한 class에 static 변수를 선언하였다. 매개변수를 this string 을 받도록 하였다.

this는 컴파일러에게 이 메서드가 string타입을 확장한 메서드라는 것을 알려주는 역활을 한다. 


그리고 메서드의 내용은 정규표현식을 사용하여 input이 전화번호인지 검사하는 코드이다.
정규표현식을 검사하는 Regex class 에 대해서는 아래 링크를 참고하자.

- C# 정규식을 사용하여 패턴 매칭(Regex, IsMatch) : http://hijuworld.tistory.com/22



이제 해당 확장메서드를 사용해보자.


아래코드는 그 예시이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Program
{        
    static void Main(string[] args)
    {
        String test = "010-9559-4444";
        if (test.IsValidPhone())
            Console.WriteLine("일치");
        else
            Console.WriteLine("불일치");
 
        test = "012-9559-4444";
        if (test.IsValidPhone())
            Console.WriteLine("일치");
        else
            Console.WriteLine("불일치");
    }
}
cs


실제로 String 클래스의 메서드처럼 사용하면 된다.



참고자료 : 크로스 플랫폼 개발을 위한 C# 7과 닷넷 코어 2.0 ( 에어콘 출판사) 7장



Posted by 꿈만은공돌
,

C언어에서 가장 불편한 것을 꼽으라면 문자열 처리가 그중 하나가 된다.


C#에서는 문자열을 쉽고 편리하게 사용할 수 있게 String 이라는 편리한 class를 제공해준다.


그리고 class는 다양한 함수들을 가지고 있는데 잘 사용한다면 문자열들을 다루는데 많은 도움이 된다.


1. Length : 문자열의 길이를 반환 한다.

아래 예제는 abcd def 라는 문자열에 길이인 8을 size 변수에 넣는 것을 알 수 있다.


1
2
3
4
5
string test = "abcd efg";
 
//Length : 글자 길이
int size = test.Length; //8
Console.WriteLine("size : " + size);
cs


출력결과

size : 8




2. Split : 특정 조건으로 문자를 쪼갤 수 있다.

아래 예제는 abcd efg 라는 문자열을 Split(' ') 으로 띄어쓰기 된 부분을 쪼개서 abcd와 efg로 나누는 것을 볼 수 있다.  


1
2
3
4
5
6
string test = "abcd efg";
 
string[] arrTest = test.Split(' '); 
foreach(string str in arrTest) {
    Console.WriteLine(str);
});
cs


출력결과 

abcd

def




3. IndexOf : 특정 문자의 위치를 찾는다. 첫번재 글자는 0을 기준으로 한다.

아래 예제는 abcd efg 문자열에서 Indexof(' ') 해서 공백을 찾아 해당 위치를 반환한다.


1
2
3
4
string test = "abcd efg";
 
int indexSpace = test.IndexOf(' '); //4
Console.WriteLine("index : " + indexSpace);
cs


출력결과

index : 4





4. [index] : 특정 index에 문자를 얻을 수 있다. 0번부터 시작한다.

아래 예제는 abcd efg 에서 index가 1인 b를 반환한다.


1
2
3
4
string test = "abcd efg";
 
char cTest = test[1]; //b
Console.WriteLine("index 1 char : " + cTest);
cs


출력결과

index 1 char : b




5. Substring(시작index, 글자수) : 문자열을 시작 index부터 글자수 만큼 쪼갤 수 있다. 글자수가 없다면 끝까지 쪼갠다.

아래예제는 abcdefghi 라는 문자열을 0번째 index부터 4글자인 abcd를 쪼개서 str1에 넣고 4번째 index부터 4글자인 efgh를 쪼개서 str2에 넣고 7번째 index부터 마지막까지인 hi를 str3에 넣었다.


1
2
3
4
5
6
7
8
9
string test = "abcdefghi";
 
string str1 = test.Substring(04);  //abcd
string str2 = test.Substring(44); //efgh
string str3 = test.Substring(7); //hi
 
Console.WriteLine("str1 : " + str1);
Console.WriteLine("str2 : " + str2);
Console.WriteLine("str3 : " + str3);
cs


출력결과

str1 : abcd

str2 : efgh

str3 : hi




6. StartsWith : 특정 문자로 시작하는지 검사

아래예제는 abcd efg 라는 문자열을 ab로 시작하는지 검사하고 cd로 시작하는지 검사하여 결과를 출력한다.


1
2
3
4
5
6
7
string test = "abcd efg";
 
bool startWith_ab = test.StartsWith("ab"); //True
Console.WriteLine("startWith ab : " + startWith_ab);
 
bool startWith_cd = test.StartsWith("cd"); //False
Console.WriteLine("startWith cd : " + startWith_cd);
cs


출력결과

startWith ab : True

startWith cd : False




7. Contains : 특정 문자열이 포함 되어있는지 검사

아래 예제는 abcd efg 문자열에서 cd가 포함되어있는지와 dc가 포함되어있는지 검사하여 출력한다.


1
2
3
4
5
6
7
string test = "abcd efg";
 
bool contain_cd = test.Contains("cd"); //True
Console.WriteLine("contain cd : " + contain_cd);
 
bool contain_dc = test.Contains("dc"); //False
Console.WriteLine("contain dc : " + contain_dc);
cs


출력결과

contain cd : True

contain dc : False




8. Trim : 앞과 뒤에 빈문자를 제거한다.

아래 예제는 " abcde wef   "의 문자열에 앞뒤에 붙은 문자열을 제거하여 출력한다.


1
2
3
4
string test = " abcde wef   ";
 
string trimStr = test.Trim(); //abc
Console.WriteLine("시작"+trimStr +"끝");
cs


출력결과

시작abcde wef끝

Posted by 꿈만은공돌
,


C#에서 변수타입 String과 string 둘다 사용이 가능하다. 

두 타입의 차이는 무엇일까? 결론은 차이가 없다.

아래 소스코드는 모두 정상적으로 컴파일되며 실행된다.

물론 실행 결과역시 차이가 없다.


1
2
3
4
    string str1 = "abc";
    String str2 = "abc";
    Console.WriteLine("string Type : " + str1);
    Console.WriteLine("String Type : " + str2);



타입이름인 string과 String 에 마우스를 가져다 대보면 그 이유를 알 수 있다.



아래 이미지 처럼 string 타입에 마우스를 가져다 대면 System.String 인 것으로 나온다.

System 네임스페이스에 String 타입의 변수인 것을 알 수 있다.



String 과 string 모두 컴파일러가 System.String 으로 치환하는 것이다.


 이렇게 같은 이름에 변수명을 다양하게 지원하는것은 개발자에게 편의성을 제공하기 위함이라 생각된다. 프로그래밍 언어에 따라 문자열을 다루는 클래스를 String이나 string 둘중 하나를 사용한다. 그래서 프로그래머들이 혼동을 하기 쉽기 때문에 둘다 지원하는 것으로 생각된다. 둘다 아무런 차이가 없기때문에 C# 개발을 할때에는 신경쓰지 않고 하도록 하자.

 

 그리고 long 변수는 System.Int64 로 int형 변수는 System.Int32 로 자동치환 되게 된다.

int 변수대신 System.Int32 를 사용해도 되는데 이렇게 뒤에 붙어있는 수자인 32나 64는 해당 변수가 몇 바이트를 사용하는지를 명확하게 알려준다. Int 변수타입 등은 OS나 컴파일러에 따라 메모리 크기가 달라질 수 있는데 그런것을 명확하게 해주기 위함이다.

 위에서처럼 해당 변수에 마우스를 가져다대보면 해당 변수가 몇바이트 변수인지를 쉽게 알 수 있는 장점이 있다.


이외에도 다른 변수들도 아래처럼 치환이 이루어지게 된다. 다양한 변수타입이 존재하고 각각 어떤의미인지 알아두면 좋다. 그때그때 적절한 변수를 사용하는 것이 중요하기 때문이다.


object ->    System.Object

bool ->    System.Boolean

byte ->    System.Byte

sbyte ->    System.SByte

char ->    System.Char

int ->    System.Int32

uint ->    System.UInt32

short ->    System.Int16

ushort ->    System.UInt16

long ->    System.Int64

ulong ->   System.UInt64

float ->    System.Single

string ->    System.String

double ->    System.Double

decimal ->    System.Decimal


bool은 참과 거짓을 저장하는 변수타입이다.
uint는 unsigned int 를 짧게쓴 형태로 음수가없이 0부터 양수만을 저장하는 변수이다. 큰 양수를 저장할 때 이용하면 좋다.
 가장 마지막에 double과 decimal이 존재하는데 이것도 알아두면 좋다. 둘다 소수를 저장하기 위한 변수타입이다. 하지만 큰 차이점이 존재한다.

 double은 부동소수점 방식을 이용하고 decimal은 고정소수점 방식을 이용 부동소수점 방식은 장점으론 작은 메모리공간에 큰 소수를 저장 가능하나 정확성이 떨어진다.

고정소수점 방식은 연산 속도가 빠르고 수의 정확성이 높은데신 큰수를 저장할때 메모리를 많이 잡아 먹게 된다. double은 8byte 메모리를 사용하며 decimal은 16byte에 메모리를 사용한다.

Posted by 꿈만은공돌
,