메인 컨텐츠로 가기

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관 보기.

developerWorks에 처음 로그인하면 developerWorks프로파일이 생성됩니다.귀하의 프로파일에서 동의하신 내용이 공개되지만 이 사항은 언제든지 변경 가능합니다. 귀하의 성명(숨김으로 체크되어 있어도 표시됩니다)과 디스플레이 이름은 게시한 컨텐츠나 사이트 엑세스시 표시됩니다.

모든 정보가 안전하게 전송되었습니다.

  • 닫기 [x]

처음 developerWorks에 로그인할 때 프로파일이 작성되므로, 이를 위해 디스플레이 이름을 선택해야 합니다. 선택하신 디스플레이 이름은 developerWorks에 게시한 컨텐츠에 표시됩니다.

3글자 이상 31글자 이하의 길이로 사용 가능합니다. dW커뮤니티 내에서는 보안상 이메일주소를 제외한 다른 이름을 지정하셔야 합니다.

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관 보기.

모든 정보가 안전하게 전송되었습니다.

  • 닫기 [x]

Ruby를 사용한 텍스트 처리

Ruby의 강력한 기능을 이용하여 텍스트를 효과적으로 처리하기

Santhosh Krishnamoorthy, Staff Software Engineer, IBM
Photo of Santhosh Krishnamoorth
Santhosh Krishnamoorthy는 인도 방갈로어에 있는 IBM Software Labs TXSeries 팀의 테스트 엔지니어로 상호 시스템 통신 및 Java 기술 분야를 담당한다. 주요 관심사는 Ruby, Ruby on Rails 및 Python 프로그래밍이다.

요약:  Ruby는 무료이며 단순하고 확장과 이식이 가능하며 기능이 다양한 오브젝트 지향 스크립팅 언어입니다. 강력한 텍스트 처리 언어인 Ruby는 가능성이 무한합니다. 강력한 내장 라이브러리와 외부 라이브러리 세트를 갖고 있는 Ruby는 일상적으로 마주치게 되는 모든 텍스트 처리 작업을 해결할 수 있는 실용적인 방안이 될 수 있습니다.

원문 게재일:  2009 년 8 월 18 일 번역 게재일:   2009 년 11 월 03 일
난이도:  중급 영어로:  보기 PDF:  A4 and Letter (45KB | 15 pages)Get Adobe® Reader®
페이지뷰:  1858 회
의견:  


Ruby에는 Perl이나 Python과 같은 페이지에서 텍스트를 처리할 수 있는 강력한 기능이 있다. 이 기사에서는 Ruby의 텍스트 데이터 처리 기능과 Ruby를 사용하여 CSV 데이터나 XML 데이터와 같은 형식의 텍스트 데이터를 효과적으로 처리하는 방법에 대해 간단하게 살펴본다.

Ruby 문자열

자주 사용하는 약어

  • CSV: Comma Separated Values
  • REXML: Ruby Electric XML
  • XML: Extensible Markup Language

Ruby의 문자열은 텍스트 데이터를 유지, 비교, 조작할 수 있는 강력한 도구이다. Ruby의 문자열은 하나의 클래스로 String::new를 호출하거나 단지 리터럴 값을 할당하여 인스턴스화할 수 있다.

문자열에 값을 할당할 경우에는 한 쌍의 작은따옴표(')나 큰따옴표를 사용하여 해당 값을 둘러싼다. 작은따옴표와 큰따옴표를 사용하여 문자열을 지정하는 방식은 몇 가지가 있다. 큰따옴표를 사용하면 첫 머리에 백슬래시를 사용하는 Escape 시퀀스가 가능하며 또한 #{} 연산자를 사용하여 문자열 안에 있는 표현식을 평가할 수 있다. 문자열을 작은따옴표로 둘러싸면 순수한 리터럴이된다.

Listing 1에는 관련 예제가 표시되어 있다.


Listing 1. Ruby에서 문자열 정의하기


message = 'Heal the World…'

puts message

message1 = "Take home Rs #{100*3/2} "

puts message1

Output :

# ./string1.rb

# Heal the World…

# Take home Rs 150


여기서 첫 번째 문자열은 한 쌍의 작은따옴표를 사용하여 정의하였다. 두 번째는 한 쌍의 큰따옴표를 사용하였다. 두 번째 예에서는 #{} 안에 있는 표현식을 먼저 평가한 후에 값을 표시한다.

문자열을 정의하는 또 다른 유용한 방식으로는 다중 라인 문자열 정의를 사용하는 방법이 있다.

여기부터는 대화식 Ruby 콘솔인 irb>>를 사용하여 설명한다. Ruby 설치판을 사용하여 이 콘솔을 설치해야 한다. 설치하지 않은 경우 irb Ruby gem을 가져와서 설치한다. 이는 Ruby와 그 모듈을 학습하는 데 필요한 매우 유용한 도구이다. 설치한 경우 irb>> 명령을 사용하여 실행할 수 있다.


Listing 2. Ruby에서 다중 라인 문자열 정의하기


irb>> str = >>EOF

irb>> "hello world

irb>> "how do you feel?

irb>> "how r u ?

irb>> EOF

"hello, world\nhow do you feel?\nhow r u?\n"

irb>> puts str

hello, world
how do you feel?
how r u?


Listing 2에서 \n(줄 바꾸기) 문자를 포함하여 >>EOFEOF 사이에 있는 모든 것은 문자열의 일부로 간주된다.

Ruby 문자열 클래스에는 문자열에 저장된 데이터를 조작하고 처리하기 위한 강력한 메소드 세트가 있다. Listing 3, 45에는 이러한 메소드가 일부 표시되어 있다.


Listing 3. Ruby에서 문자열 병합하기


irb>> str = "The world for a horse"    # String initialized with a value

The world for a horse

irb>> str*2                     # Multiplying with an integer returns a 
                                         # new string containing that many times
                                         # of the old string.

The world for a horseThe world for a horse

irb>> str + " Who said it ? "      # Concatenation of strings using the '+' operator

The world for a horse Who said it ?

irb>> str<<" is it? "	  # Concatenation using the '<<' operator

The world for a horse is it?


하위 문자열을 추출하고 이 문자열의 일부를 조작하기


Listing 4. Ruby에서 문자열을 추출하고 조작하기


irb>> str[0]	# The '[]' operator can be used to extract substrings, just 
                        # like accessing entries in an array.
                        # The index starts from 0.
84			# A single index returns the ascii value
                        # of the character at that position

irb>> str[0,5]	# a range can be specified as a pair. The first is the starting 
                        # index , second is the length of the substring from the
                        # starting index.

The w

irb>> str[16,5]="Ferrari"   # The same '[]' operator can be used
                                  # to replace substrings in a string
                                  # by using the assignment like '[]='
irb>>str

The world for a Ferrari

Irb>> str[10..22]		# The range can also be specified using [x1..x2] 

for a Ferrari

irb>> str[" Ferrari"]=" horse"	# A substring can be specified to be replaced by a new
                               # string. Ruby strings are intelligent enough to adjust the
                               # size of the string to make up for the replacement string.

irb>> s

The world for a horse

irb>> s.split	       # Split, splits the string based on the given delimiter
                               # default is a whitespace, returning an array of strings.

["The", "world", "for", "a", "horse"]

irb>> s.each(' ') { |str| p str.chomp(' ') }

                               # each , is a way of block processing the
			       # string splitting it on a record separator
			       # Here, I use chomp() to cut off the trailing space

"The"
"world"
"for"
"a"
"horse"


Ruby 문자열 클래스에서는 대소문자를 서로 변경하고, 길이를 구하고, 레코드 분리 문자를 제거하고, 문자열을 검색하고, 문자열을 암호화하거나 해독하는 메소드 등과 같은 매우 다양한 유틸리티 메소드를 사용할 수 있다. 또 다른 유용한 방법은 문자열이 변경되지 않도록 할 수 있는 freeze 메소드이다. 문자열 str(str.freeze)에서 이 메소드를 호출하면 str은 수정할 수 없다.

또한 Ruby에는 소멸자(destructor) 메소드라고 하는 것이 있다. 느낌표(!)로 끝나는 메소드는 문자열을 영구적으로 수정한다. 끝에 느낌표가 없는 일반 메소드는 메소드를 호출한 문자열의 사본을 수정하고 리턴한다. 반면에 느낌표로 끝나는 메소드는 메소드를 호출한 문자열을 수정한다.


Listing 5. Ruby 문자열 다루기: 영구적으로 문자열 수정하기


irb>> str = "hello, world"

hello, world

irb>> str.upcase

HELLO, WORLD

irb>>str		       # str, remains as is.

Hello, world

irb>> str.upcase!	       # here, str gets modified by the '!' at the end of 
                               # upcase.
HELLO, WORLD

irb>> str

HELLO, WORLD


Listing 5에서 str의 문자열은 upcase! 메소드에 의해 수정되지만 upcase 메소드는 대소문자가 변경된 문자열의 사본을 리턴한다. 이러한 느낌표(!)가 있는 메소드는 때로는 매우 유용하다.

Ruby 문자열은 매우 강력하다. 일단 문자열에서 데이터를 캡처하면 다양한 메소드를 사용하여 매우 쉽고 효과적으로 데이터를 처리할 수 있다.


CSV 파일 처리하기

CSV 파일은 표로된 데이터를 표현하는 일반적인 방법이며 연락처 세부사항이 있는 연락처 목록과 같은 스프레드시트에서 데이터를 내보낼 때 자주 사용하는 형식이다.

Ruby에는 이러한 파일을 처리할 수 있는 강력한 라이브러리가 있다. csv는 CSV 파일을 처리하는 Ruby 모듈이다. 이 모듈에는 CSV 파일을 작성하고, 읽고, 구문 분석할 수 있는 메소드가 있다.

Listing 6의 예제에는 Ruby csv 모듈을 사용하여 이러한 CSV 파일을 작성하고 구문 분석하는 방법이 표시되어 있다.


Listing 6. CSV 파일 다루기: CSV 파일의 작성 및 구문 분석


require 'csv'

writer = CSV.open('mycsvfile.csv','w')

begin

	print "Enter Contact Name: "

	name = STDIN.gets.chomp

	print "Enter Contact No: "

	num = STDIN.gets.chomp

	s = name+" "+num

	row1 = s.split

	writer << row1

	print "Do you want to add more ? (y/n): "

	ans = STDIN.gets.chomp

end while ans != "n"

writer.close

file = File.new('mycsvfile.csv')

lines = file.readlines

parsed = CSV.parse(lines.to_s)

p parsed

puts ""

puts "Details of Contacts stored are as follows..."

puts ""

puts "-------------------------------"

puts "Contact Name | Contact No"

puts "-------------------------------"

puts ""

CSV.open('mycsvfile.csv','r') do |row|

	puts row[0] + " | " + row[1]	

	puts ""
end


Listing 7에는 출력 내용이 표시되어 있다.


Listing 7 CSV 파일 다루기: CSV 파일 출력의 작성 및 구문 분석


Enter Contact Name: Santhosh

Enter Contact No: 989898

Do you want to add more ? (y/n): y

Enter Contact Name: Sandy

Enter Contact No: 98988

Do you want to add more ? (y/n): n

Details of Contacts stored are as follows...

---------------------------------
Contact Name | Contact No
---------------------------------

Santhosh | 989898

Sandy | 98988


이제 예제를 간단히 살펴보자.

먼저, Ruby csv 모듈을 포함한다(require 'csv').

이름이 mycsvfile.csv인 CSV 파일을 작성하기 위해 CSV.open() 호출을 사용하여 이 파일을 연다. 이렇게 하면 기록기 오브젝트가 리턴된다.

이 예제에서는 간단한 연락처 목록이 있는 CSV 파일을 작성하고 인명과 전화번호를 저장한다. 이 예제의 루프를 통해 사용자는 연락처 이름과 전화번호를 입력하게 된다. 이름과 전화번호를 하나의 문자열로 병합한 후 다시 두 개의 문자열로 구성된 하나의 배열로 분리한다. 이 배열을 기록기 오브젝트에 전달하여 CSV 파일에 쓴다. 따라서 한 쌍의 CSV 값이 이 파일에 하나의 라인으로 저장된다.

루프가 끝나면 모든 과정이 완료된다. 이제 기록기를 닫고 파일에 있는 데이터를 저장한다.

다음 단계에서는 작성한 CSV 파일을 구문 분석한다.

이 파일을 열고 구문 분석하는 한가지 방법은 새로운 이름의 CSV 파일을 사용하는 새 File 오브젝트를 작성하는 것이다.

readlines 메소드를 호출하여 이 파일의 모든 라인을 읽어서 lines라고 하는 배열로 보낸다.

lines.to_s를 호출하여 lines 배열을 String 오브젝트로 변환하고 이 문자열을 CSV 데이터를 구문 분석하여 중복 배열로 해당 내용을 리턴하는 CSV.parse 메소드로 전달한다.

다음에는 이 파일을 열고 구문 분석하는 또 다른 방법이 표시되어 있다. 읽기 모드로 호출하는 CSV.open 메소드를 사용하여 다시 이 파일을 연다. 이렇게 하면 여러 개의 행으로 구성된 하나의 배열이 리턴된다. 일부 서식을 사용하여 각 행을 인쇄하여 연락처 세부사항을 표시한다. 여기에 있는 각 행은 CSV 파일의 한 라인에 해당한다.

아는 바와 같이 Ruby에는 CSV 파일과 데이터를 다룰 수 있는 강력한 모듈이 있다.


XML 파일 다루기

Ruby에는 XML 파일을 처리할 수 있는 REXML이라고 하는 강력한 내장 라이브러리가 있다. 이 라이브러리를 사용하여 XML 문서를 읽고 구문 분석할 수 있다.

이러한 XML 파일을 살펴보고 Ruby와 REXML을 사용하여 구문 분석을 해보자.

아래의 간단한 XML 파일에는 온라인 쇼핑몰에서 일반적으로 사용하는 쇼핑 카트의 내용이 표시되어 있다. 이 파일은 다음과 같은 요소로 구성되어 있다.

  • cart – root 요소
  • user - 쇼핑 중인 사용자
  • item - 사용자가 카드에 추가한 품목
  • id, pricequantity - 품목의 하부 요소

Listing 8에는 XML의 구조가 표시되어 있다.


Listing 8. XML 파일 다루기: 샘플 XML 파일


<cart id="userid">

<item code="item-id">

	<price>

		<price/unit>

	</price>

	<qty>

		<number-of-units>

	</qty>

</item>

</cart>


다운로드로 이동하여 샘플 XML 파일을 다운로드한다. 이제 REXML을 사용하는 트리를 통해 이 XML 파일을 로드하고 구문 분석하자.


Listing 9. XML 파일 다루기: XML 파일의 구문 분석


require 'rexml/document'

include REXML

file = File.new('shoppingcart.xml')

doc = Document.new(file)

root = doc.root

puts ""

puts "Hello, #{root.attributes['id']}, Find below the bill generated for your purchase..."

puts ""

sumtotal = 0

puts "-----------------------------------------------------------------------"

puts "Item\t\tQuantity\t\tPrice/unit\t\tTotal"

puts "-----------------------------------------------------------------------"

root.each_element('//item') { |item| 

code = item.attributes['code']

qty = item.elements["qty"].text.split(' ')

price = item.elements["price"].text.split(' ')

total = item.elements["price"].text.to_i * item.elements["qty"].text.to_i

puts "#{code}\t\t  #{qty}\t\t          #{price}\t\t         #{total}"

puts ""

sumtotal += total

}

puts "-----------------------------------------------------------------------"

puts "\t\t\t\t\t\t     Sum total : " + sumtotal.to_s

puts "-----------------------------------------------------------------------"


Listing 10에는 출력이 표시되어 있다.


Listing 10. XML 파일 다루기: XML 파일 출력의 구문 분석


Hello, santhosh, Find below the bill generated for your purchase...

-------------------------------------------------------------------------
Item            Quantity                Price/unit              Total
-------------------------------------------------------------------------
CS001             2                          100                      200

CS002             5                          200                     1000

CS003             3                          500                     1500

CS004             5                          150                      750

-------------------------------------------------------------------------
                                                         Sum total : 3450
--------------------------------------------------------------------------


Listing 9에 있는 예제에서는 쇼핑 카트 XML 파일을 구문 분석하여 전체 개별 품목과 총 구매 금액이 표시된 청구서(Listing 10)를 생성한다.

이 예제를 간단히 살펴보자.

먼저, Ruby의 REXML 모듈을 포함한다. 이 모듈에는 XML 파일을 구문 분석을 할 수 있는 메소드가 있다.

shoppingcart.xml 파일을 열고 이 파일에서 Document 오브젝트를 작성한다. 이 Document 오브젝트에는 구문 분석한 XML 파일이 포함되어 있다.

이 문서의 루트를 요소 오브젝트 root에 할당한다. 그러면 문서의 루트가 해당 XML의 cart 태그를 가리키게 된다.

각 요소 오브젝트에는 속성 오브젝트가 있으며 이 오브젝트는 요소 속성 이름과 그 값이 각각 키와 값으로 구성된 일종의 해시이다. 여기에서는 root.attributes['id']를 통해 root 요소의 속성 id(이 경우에는 userid) 값을 제공한다.

다음에는 sumtotal을 0으로 초기화하고 헤더를 표시한다.

또한 각 요소 오브젝트에는 Elements라고 하는 오브젝트와 그 하부 요소를 액세스할 수 있는 each 및 [] 메소드가 있다. 이 블록은 XPath 표현식(//item)에서 지정된 이름이 itemroot 요소의 모든 하부 요소를 통해 실행된다. 또한 각 요소 오브젝트에는 이러한 요소의 텍스트 값을 유지하는 text 속성이 있다.

다음에는 item 요소의 code 속성과 priceqty 요소의 텍스트 값을 가져와서 품목의 총계를 계산한다. 청구서에 세부사항을 표시한다. 또한 품목 총계를 sumtotal에 추가한다.

마지막으로 품목 총계의 합계를 표시한다.

REXML와 Ruby를 사용하여 XML 파일을 구문 분석하는 것이 얼마나 쉽고 단순한지 이 예제를 통해 알 수 있다. XML 파일을 빠르게 작성하고 요소와 그 속성을 추가하고 삭제하기가 매우 쉽다.


Listing 11. XML 파일 다루기: XML 파일의 생성


doc = Document.new

doc.add_element("cart1", {"id" => "user2"})

cart = doc.root.elements[1]

item = Element.new("item")

item.add_element("price")

item.elements["price"].text = "100"

item.add_element("qty")

item.elements["qty"].text = "4"

cart .elements << item


Listing 11에서는 cartitem 요소 그리고 그 하부 요소를 사용하여 XML 구조를 작성한다. 이러한 요소에 값을 채운 후 Document 루트에 이 요소를 추가한다.

마찬가지로 Elements 오브젝트의 delete_elementdelete_attribute 메소드를 사용하여 요소와 속성을 삭제한다.

위의 예제는 트리 구문 분석(tree parsing)이라고 한다. XML 문서를 구문 분석하는 또 다른 방법은 스트림 구문 분석(stream parsing)이라고 한다. 이 방법은 트리 구문 분석보다 빠르며 속도가 중요한 부분에 사용될 수 있다. 스트림 구문 분석은 이벤트를 기반으로 하며 리스너와 함께 동작한다. 태그를 발견하면 리스너를 호출하여 구문 분석을 한다.

Listing 12에는 이에 대한 예제가 표시되어 있다.


Listing 12. XML 파일 다루기: 스트림 구문 분석


require 'rexml/document'

require 'rexml/streamlistener'

include REXML

class Listener

  include StreamListener

  def tag_start(name, attributes)

    puts "Start #{name}"

  end

  def tag_end(name)

    puts "End #{name}"

  end

end

listener = Listener.new

parser = Parsers::StreamParser.new(File.new("shoppingcart.xml"), listener)

parser.parse


Listing 13에서 출력 결과가 표시되어 있다.


Listing 13. XML 파일 다루기: 스트림 구문 분석 출력 결과


Start cart

Start item

Start price

End price

Start qty

End qty

End item

Start item

Start price

End price

Start qty

End qty

End item

Start item

Start price

End price

Start qty

End qty

End item

Start item

Start price

End price

Start qty

End qty

End item

End cart


따라서 REXML과 Ruby에는 매우 효과적이고 직관적인 방식으로 XML 데이터를 다루고 조작할 수 있는 강력한 조합 기능이 있다.


요약

Ruby에는 텍스트를 빠르고, 강력하고 효과적으로 처리할 수 있는 내장 라이브러리와 외부 라이브러리가 있다. 사용자는 이러한 기능을 이용하여 직면할 수 있는 다양한 텍스트 형식의 데이터 처리 요구를 단순화하고 개선할 수 있다. 이 기사에서는 Ruby의 일부 기능만을 다루었다. 그러나 Ruby에는 보다 다양한 기능이 있다.

Ruby는 사용자에게 반드시 필요한 유용한 도구이다.



다운로드 하십시오

설명이름크기다운로드 방식
Sample code for the articlesample-code.zip2KBHTTP

다운로드 방식에 대한 정보


참고자료

교육

제품 및 기술 얻기

토론

필자소개

Photo of Santhosh Krishnamoorth

Santhosh Krishnamoorthy는 인도 방갈로어에 있는 IBM Software Labs TXSeries 팀의 테스트 엔지니어로 상호 시스템 통신 및 Java 기술 분야를 담당한다. 주요 관심사는 Ruby, Ruby on Rails 및 Python 프로그래밍이다.

잘못된 도움말 신고

부정사용 신고

감사합니다. 이 항목은 운영자가 관심을 표시했습니다.


잘못된 도움말 신고

부정사용 신고

제출실패 신고. 나중에 다시 실행해주세요.


디벨로퍼웍스 로그인


IBM ID가 필요하세요?
IBM ID를 잊으셨습니까?


비밀번호를 잊으셨습니까?
비밀번호 변경

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관.

 


developerWorks에 처음 로그인하면 developerWorks프로파일이 생성됩니다.귀하의 프로파일에서 동의하신 내용이 공개되지만 이 사항은 언제든지 변경 가능합니다. 귀하의 성명(숨김으로 체크되어 있어도 표시됩니다)과 디스플레이 이름은 게시한 컨텐츠나 사이트 엑세스시 표시됩니다.

화면상에 보여지는 닉네임을 정하세요.

처음 developerWorks에 로그인할 때 프로파일이 작성되므로, 이를 위해 디스플레이 이름을 선택해야 합니다. 선택하신 디스플레이 이름은 developerWorks에 게시한 컨텐츠에 표시됩니다.

3글자 이상 31글자 이하의 길이로 사용 가능합니다. dW커뮤니티 내에서는 보안상 이메일주소를 제외한 다른 이름을 지정하셔야 합니다.

3개의 &이나 대쉬를 포함해주시고 31글자내로 제한해주세요.


developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관.

 


아티클 순위

의견

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=20
Zone=XML
ArticleID=442920
ArticleTitle=Ruby를 사용한 텍스트 처리
publish-date=08182009
author1-email=santhoshk@in.ibm.com
author1-email-cc=dwxed@us.ibm.com

태그

Help
검색 필드를 사용하여 My developerWorks 내에서 해당 태그가 사용된 모든 종류의 컨텐츠를 검색하십시오.

태그를 더 많이 보거나 적게 보기 위해 슬라이더 막대를 사용하십시오.

인기 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 최고 인기 태그를 보여줍니다.

내 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 귀하의 태그를 보여줍니다.

검색 필드를 사용하여 My developerWorks 내에서 해당 태그가 사용된 모든 종류의 컨텐츠를 검색하십시오. 인기 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 최고 인기 태그를 보여줍니다. 내 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 귀하의 태그를 보여줍니다.