윈도우 PHP Web Programming (14) - PHP 문자열 함수

1. string addslashes(string str)

문자열에 가 있으면 역 스래시(\)를 붙여준다. 반대는 stripslashes이다.

2. string chop(string str)

문자열의 뒷 부분의 공백을 제거한다. ltrim은 앞 부분의 공백을 제거하며, trim은 앞과 뒤의 공백을 제거한다.

3. string chr(int ascii)

ASCII에 해당하는 문자를 반환한다.

4. string crypt(string str, string [salt])

주어진 문자열을 암호화 한다. 두 번째 인자가 생략되면 시스템이 임의로 암호화 방식을 결정한다. 암호화 방식은 DES, MD5 등을 사용한다. 암호를 해독하는 함수는 없다.

5. echo(string arg1, string [argn])

하나 이상의 문자열을 출력한다. Print 함수와 같은 기능을 수행한다.

6. int ereg(string pattern, string str, array [regs])

두 번째 문자열(str)에서 첫 번째 문자열(pattern)을 찾는다. 두 번째 문자열에 ()가 포함되어 있으면, 세 번째 인자가 필요하다. ereg 함수는 대소문자를 구별하지만, eregi 함수는 대소문자를 구별하지 않는다.

7. string ereg_replace(string pattern, string replacement, string str)

세 번째 문자열(str)에서 첫 번째 문자열(pattern)을 찾아 두 번째 문자열(replacement)로 바꾼 후 그 값을 반환한다. 일치하는 문자가 없으면 원래의 문자열을 반환한다. ereg_replace 함수는 대소문자를 구분한다. eregi_replace 함수는 대소문자를 구분하지 않는다.

8. array explode(string separator, string str)

첫 번째 인자 separator를 구분자로 하여 두 번째 문자열 str을 나누어 배열로 저장한다. split 함수와 유사한 기능이다. implode 함수는 반대 기능을 한다. 구분자 문자는 배열에 저장하지 않는다.

9. string htmlentities(string str)

문자열의 특정 문자들을 HTML 개체들로 변환한 결과 값을 반환한다.

10. string htmlspecialchars(string str)

게시판이나 방명록 등에서 사용자가 입력한 &, , <, >와 같은 특수 문자를 화면에 출력 가능하도록 &amp, &quot, &lt, &gt와 같은 HTML 코드로 변경한다. 기타 다른 특수 문자를 변환하기 위해서는 htmlentities 함수를 사용한다.

11. string implode(string glue, array pieces)

배열로 나누어진 문자열을 하나의 문자열로 합친다. glue는 합친 문자열의 구분자이다. Explode 함수의 반대 기능이며, join 함수와 같은 기능을 수행한다.

12. string join(array pieces, string glue)

implode 함수와 같은 기능을 수행한다.

13. string ltrim(string str)

문자열의 앞 부분의 공백을 제거한다. chop 함수는 뒷 부분의 공백을 제거하며, trim 함수는 앞 뒤 부분의 공백을 제거한다.

14. string nl2br(string str)

문자열에 포함된 개행 문자를 <BR> 태그로 바꾼다. 사용자가 enter 키를 입력한 곳을 찾아 그곳에 <BR> 태그를 삽입하여 저장하기 위해 사용된다.

15. into rd(string str)

주어진 문자를 ASCII 값으로 반환한다. chr 함수의 반대 기능이다.

16. int preg_match(string pattern, string subject, array [matches])

문자열 subject에서 문자열 pattern과 일치하는 패턴이 있는지 찾아서, 있다면 그 패턴을 array에 저장하고 1(TRUE)를 반환한다.

Pattern 유형은 다음과 같다.

- /he/I he와 일치하는 패턴

- /[abc]/ a, b, c 중 어느 하나와 일치하는 패턴

- /[a-z]/ a부터 z까지 문자 중 어느 한 문자와 일치하는 패턴

- /[a-zA-Z]/ a부터 z, A부터 Z까지 문자 중 어느 한 문자와 일치하는 패턴

- /[^0-9]/ 숫자가 아닌 패턴

- /[\w]{3}/ 일반 문자가 3번 이상 연속으로 반복되는 패턴

- /[\d]{1,5}/ 숫자가 1번 이상 5번 이하 연속으로 반복되는 패턴

- /[\W]{3,}/ 일반 문자가 아닌 문자가 3번 이상 연속으로 반복되는 패턴

- /?/ 문자가 없거나 임의의 한 문자인 패턴

- /./ 줄 바꿈 문자가 아닌 임의의 문자인 패턴

- /+/ 선행 패턴을 만족하는 문자() 1번 이상 반복되는 패턴

- /*/ 선행 패턴을 만족하는 문자() 1번 이상 반복되는 패턴

17. print(string arg)

문자열을 출력한다.

18. int printf(string format, mixed [args])

문자열을 포맷하여 출력한다.

19. int quotemeta(string str)

Meta 문자 앞에 \문자를 삽입한다.

20. string sprintf(string format, mixed [args] )

문자열을 포맷하여 출력한다. Printf 함수와 동일한 기능이지만, sprintf 함수는 수행 결과를 호출한 곳에 반환한다.

21. array split(string pattern, string str, int [limit])

문자열 str pattern 구분자를 사용하여 나누어 배열에 저장한다. 오류가 발생하면 FALSE를 반환하고, limit은 나누어 저장할 문자열의 개수로 생략 가능하다.

22. int strcasecmp(string str1, string str2)

대소문자를 구분하지 않고 두 문자열을 비교한다.

23. string strchr(string haystack, string needle)

문자열 haystack을 검사하여 문자열 needle이 처음 나타난 위치부터 끝까지 값을 반환한다. 찾는 문자열이 없는 경우 FALSE를 반환한다.

24. int strcmp(string str1, string str2)

두 문자열을 배교하여 같으면 0, str1 str2보다 작으면 - 값을, 크면 + 값을 반환한다.

25. string stripslashes(string str)

문자열에서 역 슬래시 문자를 제거하여 반환한다.

26. string stristr(string str, string, find_str)

문자열 str에서 문자열 find_str을 찾아서 일치하는 부분부터 끝까지 반환한다. 대소문자를 구분하지 않는다. 찾는 문자열이 없으면 FALSE를 반환한다.

27. int strlen(string str)

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

28. int strpos(string haystack, string needle, int [offset])

문자열 haystack을 검사하여 문자열 needle이 처음 나타난 위치 값을 숫자로 반환한다. 찾지 못하면 FALSE를 반환한다. Offset은 검사를 시작할 위치이다.

29. string strrchr(string hatstack, string needle)

문자열 haystack을 검사하여 문자열 needle이 마지막으로 나타난 위치부터 끝까지의 문자열을 반환한다.

30. string str_replace(string str1, string str2, string str3)

문자열 str3에서 문자열 str1을 찾아서 문자열 str2로 바꾼다. ereg_replace 함수보다 처리 속도가 빠르다.

31. string strrev(string str)

문자열의 글자 위치를 정반대로 바꾸어 반환한다.

32. int strrpos(string haystack, string needle)

문자열 haystack을 검사하여 문자열 needle이 마지막으로 나타난 위치의 값을 숫자로 반환한다.

33. string strstr(string str, string find_str)

문자열 str에서 문자열 find_str을 찾아서 일치하는 부분부터 끝까지 문자열을 반환한다. 대소문자를 구별한다.

34. string strtolower(string str)

문자열을 소문자로 변환하여 반환한다.

35. string strtoupper(string str)

문자열을 대문자로 변환하여 반환한다.

36. string substr(string str, int start, int length)

문자열 str start 위치부터 length 만큼의 문자를 반환한다. Length가 생략되면 끝까지 반환된다.

37. string trim(string str)

문자열의 앞과 뒤의 공백을 제거하고 반환한다.

38. string ucfirst(string str)

문자열의 첫 문자가 영문자이면 대문자로 변경한 후 문자열을 반환한다.

39. string ucwords(string str)

문자열 내의 모든 단어들의 첫 문자를 대문자로 변환하고, 문자열을 반환한다.

주의 : cpu가 virtualization을 지원하지 않으면 안된다.

1. virtual box를 설치한다.(2.1.2)
2. 새로운 vm을 만든다. 이때 주의할 것은 반드시 VT-x / AMD-v가 사용 가능한 상태가 되어야 한다.
3. os/2 warp 4 iso 이미지를 cd에 마운트 상태로 한다.
4. iso 이미지를 열어보면 BOOTIMGS 디렉토리 아래에 DISK_0_1.IMG, DISK_2.IMG 파일이 있다. 이 중 DISK_0_1.IMG를 플로피 디스크로 마운트한다.
5. vm을 시작한다. 부트 메뉴에서 2. removable media를 선택한다. 그럼 아래의 화면을 볼 수 있다.


6. 로고가 지나고 나면 대충 다음 다음을 눌러서 진행한다(무책임한 게시글)
7. 설치가 완료되면 cd와 플로피의 마운트를 해제하고 enter를 눌러서 재부팅한다.
8. 부팅이 되면 시커먼 화면만 나온다 .ALT+F2를 누르면 부팅시 어떤 일이 진행되는 지를 확인할 수 있다.
9. 그 다음부터는 익숙한 GUI 환경에서의 시스템 설정이다. 입맛대로..... 진행이 잘 되면 열심히 파일을 복사하는 화면을 확인할 수 있다.


10. 설정과 설치가 끝나면 다시 재부팅이다.
11. 어쨋든 이놈은 부팅할때 아무것도 안뜨고 시커먼 화면이다. 역시 ALT+F2를 눌러서 무슨 일을 꾸미는지 확인하자. Virtual box에서 network설정을 어떻게 하는지 몰라서 host랑 똑같이 했더니 에러를 뱉는다. 그냥 무시했다. 나중에 고치지 뭐....
12. 재부팅 되고 나면 또 열심히 복사한다.
13. 설치 과정간의 광고를 보면 "Lotus가 짱입니다" 따위의 글을 볼 수 있다. 하긴 1994년에 나온 녀석이니........-_-;
14. 아무튼 설치 과정은 무지하게 길다.....
15. 다 끝나고 나면 이런 화면이 뜬다.


16. 윈도우 3.x 정도의 느낌........ 프리쉘은 없나 -_-;
Posted by soulreaver

파이썬으로 재귀하향 파서 만들기(2)

제공 : 한빛 네트워크
저자 : Paul McGuire
역자 : 주재경
원문 : Building Recursive Descent Parsers with Python

[이전 기사 보기]
파이썬으로 재귀하향 파서 만들기(1)

예제 프로그램

NaCl, H2O, C6H5OH와 같은 화학 공식을 처리할 필요가 있는 프로그램을 생각해 보자. 이 경우 화학 공식 문법은 하나 혹은 그 이상의 심벌을 가질 것이고 각각의 뒤에는 선택적으로 정수가 올 수 있다. BNF형식으로 이는 다음과 같다.
integer       :: '0'..'9'+cap           :: 'A'..'Z'lower         :: 'a'..'z'elementSymbol :: cap lower*elementRef    :: elementSymbol [ integer ]formula       :: elementRef+
pyparsing모듈은 Optional과 OneOrMore 클래스로 이 개념을 처리한다. elementSymbol의 정의는 2개의 인자를 갖는 생성자 Word를 사용한다. 첫 번째 인자는 시작 문자를 나타내며 첫 번째 인자 이후 뒤 따르는 문자를 나타낸다.
caps       = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"lowers     = caps.lower()digits     = "0123456789"element    = Word( caps, lowers )elementRef = element + Optional( Word( digits ) )formula    = OneOrMore( elementRef )elements   = formula.parseString( testString )
이것으로 이 프로그램은 아래의 공식을 적절할 토큰으로 처리하는 적절한 토큰화 프로그램이 된다. Pyparsing의 기본 동작은 일치하는 하위 문자열의 하나의 리스트 내에서 파싱된 모든 토큰을 리턴하는 것이다.
H2O -> ['H', '2', 'O']C6H5OH -> ['C', '6', 'H', '5', 'O', 'H']NaCl -> ['Na', 'Cl']
당연히 리스트 형태로 이 결과를 출력하기에 앞서 이 리턴된 결과로 뭔가를 하고자 할 것이다. 주어진 화학 공식에 대해 분자의 무게를 계산하고자 한다고 가정해 보자. 프로그램은 어딘가에 화학 기호와 여기에 대응되는 원자 무게를 정의해야 한다.
atomicWeight = {    "O"  : 15.9994,    "H"  : 1.00794,    "Na" : 22.9897,    "Cl" : 35.4527,    "C"  : 12.0107,    ...    }
결과를 좀더 구조화 시켜 리턴 받고자 하는 경우 파싱된 화학 기호와 관련 양을 좀더 논리적인 그룹으로 만드는 것이 좋다. 다행히도 pyparsing모듈은 이러한 목적에 맞는 Group클래스를 제공한다. elementRef선언을 elementRef = element + Optional( Word( digits ) )에서 다음과 같이 변경한다.elementRef = Group( element + Optional( Word( digits ) ) ) 화학적인 기호로 그룹화된 결과를 얻을 수 있다.
H2O -> [['H', '2'], ['O']]C6H5OH -> [['C', '6'], ['H', '5'], ['O'], ['H']]NaCl -> [['Na'], ['Cl']]
마지막으로 할 내용은 Optional클래스 생성자의 기본 인자를 사용하여 elementRef의 양을 나타내는 부분을 기본 값으로 나타내도록 하는 것이다.
elementRef = Group( element + Optional( Word( digits ),                                 default="1" ) )
모든 elementRef는 한 쌍의 값을 리턴한다. Element의 화학 기호화 그 element의 원자 번호가 이에 해당하며 크기가 주어지지 않은 경우 그 값은 1이 된다. 이제 테스크 공식은 element기호와 이에 대응하는 양을 리턴한다.
H2O -> [['H', '2'], ['O', '1']]C6H5OH -> [['C', '6'], ['H', '5'], ['O', '1'], ['H', '1']]NaCl -> [['Na', '1'], ['Cl', '1']]
마지막 단계는 각각에 대해 원자 무게를 계산하는 것이다. parseString을 호출한 후 파이썬 코드 한줄을 추가하면 된다.
wt = sum( [ atomicWeight[elem] * int(qty)                     for elem,qty in elements ] )
결과는 아래와 같다.
H2O -> [['H', '2'], ['O', '1']] (18.01528)C6H5OH -> [['C', '6'], ['H', '5'], ['O', '1'], ['H', '1']]        (94.11124)NaCl -> [['Na', '1'], ['Cl', '1']] (58.4424)
예제 2는 pyparsing 프로그램 전체를 나타내고 있다.

예제 2
from pyparsing import Word, Optional, OneOrMore, Group, ParseExceptionatomicWeight = {    "O"  : 15.9994,    "H"  : 1.00794,    "Na" : 22.9897,    "Cl" : 35.4527,    "C"  : 12.0107    }    caps = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"lowers = caps.lower()digits = "0123456789"element = Word( caps, lowers )elementRef = Group( element + Optional( Word( digits ), default="1" ) )formula = OneOrMore( elementRef )tests = [ "H2O", "C6H5OH", "NaCl" ]for t in tests:    try:        results = formula.parseString( t )        print t,"->", results,    except ParseException, pe:        print pe    else:        wt = sum( [atomicWeight[elem]*int(qty) for elem,qty in results] )        print "(%.3f)" % wt========================H2O -> [['H', '2'], ['O', '1']] (18.015)C6H5OH -> [['C', '6'], ['H', '5'], ['O', '1'], ['H', '1']] (94.111)NaCl -> [['Na', '1'], ['Cl', '1']] (58.442)
파서를 이용하여 얻게 되는 좋은 점 중의 하나는 입력 텍스트에 대해 수행하는 타당성 검토이다. wt변수 계산에서 qty문자열이 모두 숫자임을 검사해야 할 필요가 없다는 점에 혹은 올바르지 않은 인자로 인해 발생하는 ValueError를 검사할 필요가 없다는 점에 주의할 것 .

HTML 분석기

마지막 예제로 간단한 HTML 분석기를 만들어 보자. 이것은 파서 표현식에 점수를 매기는 것과 같은 포괄적인HTML 파서는 아니다. 다행히도 대부분의 웹페이지에서 핵심적인 데이터를 추출하기 위한 완벽한 HTML 문법정의가 필요한 것은 아니다. 특히 CGI가 잗동으로 생성한 부분이나 다른 응용 프로그램에 대한 부분이 그렇다.

이 예제는 특정 웹 페이지에 맞춰 제작된 작은 파서로 데이터를 추출한다. 이 경우에 이 페이지는 NIST가 유지하고 있는 가용한 네트워크 타임 프로토콜(NTP)서버 리스트이다. 이 루틴은 어떤 NTP서버가 현재 가용한지를 나타내는 좀더 큰NTP클라이언트 프로그램 한 부분이 될 수도 있다.

HTML분석기를 만들기에 앞서 어떤 종류의 HTML 텍스를 처리하고자 하는지를 알아야 한다. 웹사이트를 방문하고 리턴되는 HTML소스를 보면 웹페이지에는 HTML테이블 내에 NTP서버의 IP주소와 이름이 나열되어 있다.

이름IP주소위치
time-a.nist.gov129.6.15.28NIST, Gaithersburg, Maryland
time-b.nist.gov129.6.15.29NIST, Gaithersburg, Maryland

이 테이블을 위해 HTML은 NTP서버 데이터를 만들기 위해 <table>, <tr>, <td>태그를 사용한다.
<table border="0" cellpadding="3" cellspacing="3" frame="" width="90%">                <tr align="left" valign="top">                        <td><b>Name</b></td>                        <td><b>IP Address</b></td>                        <td><b>Location</b></td>                </tr>                <tr align="left" valign="top" bgcolor="#c7efce">                        <td>time-a.nist.gov</td>                        <td>129.6.15.28</td>                        <td>NIST, Gaithersburg, Maryland</td>                </tr>                <tr align="left" valign="top">                        <td>time-b.nist.gov</td>                        <td>129.6.15.29</td>                        <td>NIST, Gaithersburg, Maryland</td>                </tr>       ...
이 테이블은 아주 커다란 HTML의 한 부분이다. Pyparsing을 사용하여 주어진 파서 표현식과 일치하는 텍스트를 스캔할 수 있고 전체 입력 텍스트의 한 부분에만 일치하는 파서 표현식을 정의할 수도 있다.

프로그램은 서버의 IP주소와 위치를 추출하므로 문법의 초점을 테이블의 열 방향에만 집중 시킬 수 있다.비 정상적이긴 하지만 패턴과 일치하는 값을 추출하고자 할 수도 있다.
<td> IP address </td> <td> location name </td>
너무 일반적인 표현식은 두 번째의 2개의 열 대신에 첫 번째의 2개의 열에 대응하기 때문에 <td>, </td><td>, </td>만큼 일반적인 것과 단지 일치하는 것 이상의 좀더 세부적인 규정을 원한다. 대신에 페이지의 테이블 데이터와 일치하지 않는 부분을 제거하는 좁은 의미의 탐색을 가능하게 하는 규정적인 IP주소를 사용하라.

IP주소를 만들기 위해서는 정수를 정의하고 그 다음에 사이에 마침표를 가진 네 개의 정수를 조합한다.
integer   = Word("0123456789")ipAddress = integer + "." + integer + "." + integer + "." + integer
HTML태그 <td>와 </td>를 매칭시킬 필요가 있으며 각각에 대해 파서 요소를 정의한다.
tdStart = Literal("<td>")tdEnd   = Literal("</td>")
일반적으로 <td>태그는 정렬,색깔 등에 대한 속성 구분자를 포함하기도 한다. 그러나 이것은 범용 목적의 파서가 아니라 다행하게도 복잡한<td> 태그를 사용하지 않는 단지 이 웹 페이지에 해당하는 특수 목적으로 작성된 것이다. Pyparsing의 최신 버전은 오프닝 태그에 있는 속성 구분자를 지원하는 HTML태그에 대해 도움을 주는 메서드를 가지고 있다.

마지막으로 서버위치와 일치하는 몇 가지의 표현식이 필요하다. 이것은 실제로 알파벳 데이터, 콤마, 마침표 혹은 숫자를 포함하는지 않는지를 알 길이 없는 자유롭게 만들어진 텍스트이다. 그래서 가장 간단한 선택은 종결 태그</td>에 모든 것을 다 받아들이는 것이다.pyparsing은 이런 종류의 문법 요소를 위해 SkipTo라는 이름을 가진 클래스를 가지고 있다.

이제 타임서버의 텍스트 패턴 정의에 필요한 모든 것을 가지게 되었다.
timeServer = tdStart + ipAddress + tdEnd +                  tdStart + SkipTo(tdEnd) + tdEnd
데이터를 추출하기 위해 timeserver.scanString을 호출하라. 이 함수는 입력 텍스트에 대해 일치하는 각각의 경우에 대해 시작과 마지막 문자열 위치와 일치하는 토큰을 만들어 내는 생성 함수 이다.

예제 3
from pyparsing import *import urllib# NTP서버에 대한 기본적인 텍스트 패턴 정의integer = Word("0123456789")ipAddress = integer + "." + integer + "." + integer + "." + integertdStart = Literal("<td>")tdEnd = Literal("</td>")timeServer =  tdStart + ipAddress + tdEnd + tdStart + SkipTo(tdEnd) + tdEnd# 타임서버의 리스트를 가져온다nistTimeServerURL = "http://tf.nist.gov/service/time-servers.html"serverListPage = urllib.urlopen( nistTimeServerURL )serverListHTML = serverListPage.read()serverListPage.close()for srvrtokens,startloc,endloc in timeServer.scanString( serverListHTML ):    print srvrtokens
예제 3을 실행하면 다음과 같은 토큰 데이터를 얻는다.
[' <td>', '129', '.', '6', '.', '15', '.', '28', '</td> ', ' <td>', 'NIST, Gaithersburg, Maryland', '</td> '][' <td>', '129', '.', '6', '.', '15', '.', '29', '</td> ', ' <td>', 'NIST, Gaithersburg, Maryland', '</td> '][' <td>', '132', '.', '163', '.', '4', '.', '101', '</td> ', ' <td>', 'NIST, Boulder, Colorado', '</td> '][' <td>', '132', '.', '163', '.', '4', '.', '102', '</td> ', ' <td>', 'NIST, Boulder, Colorado', '</td> ']:
이 결과를 살펴보면 몇 가지를 바로 알 수 있다. 파서는 IP주소를 구분 마침표와 하위필드를 가진 각각의 토큰으로 기록한다는 것이 한 가지 이다. Pyparsing이 이 필드를 한 개의 문자열 토큰으로 조합하기 위해 파싱하는 동안 몇 가지 일을 할 수 있다면 참 좋을 것이다. Pyparsing Combine클래스는 이 일을 한다. IP주소에 대해 리턴되는 하나의 문자열 토큰을 얻기위해ipAddress정의를 다음과 같이 수정한다.
ipAddress = Combine( integer + "." + integer + "." + integer + "." + integer )
두 번째로 알 수 있는 것은 결과가 테이블의 열을 표시하는 HTML 태그를 열고 닫는 것을 포함하고 있다. 파싱이 진행되는 동안 이 태그가 중요한 반면에 태그 그 자체는 추출된 데이터에 관심을 두지 않는다. 리턴되는 토큰 데이터에서 이 들을 무시하려면 suppress메서드를 사용한다.
tdStart = Literal("<td>").suppress()tdEnd   = Literal("</td>").suppress()
예제 4
from pyparsing import *import urllib# NTP서버에 대한 기본적인 텍스트 패턴 정의integer = Word("0123456789")ipAddress = Combine( integer + "." + integer + "." + integer + "." + integer )tdStart = Literal("<td>").suppress()tdEnd = Literal("</td>").suppress()timeServer =  tdStart + ipAddress + tdEnd + tdStart + SkipTo(tdEnd) + tdEnd# 타임서버 리스트를 가져온다nistTimeServerURL = "http://tf.nist.gov/service/time-servers.html"serverListPage = urllib.urlopen( nistTimeServerURL )serverListHTML = serverListPage.read()serverListPage.close()for srvrtokens,startloc,endloc in timeServer.scanString( serverListHTML ):    print srvrtokens
프로그램 예제4를 실행하여 리턴되는 토큰은 부분적으로 개선되었다.
['129.6.15.28', 'NIST, Gaithersburg, Maryland']['129.6.15.29', 'NIST, Gaithersburg, Maryland']['132.163.4.101', 'NIST, Boulder, Colorado']['132.163.4.102', 'NIST, Boulder, Colorado']
마지막으로 이 토큰에 결과를 더하면 속성 이름으로 이들을 엑세스 할 수 있다. 이것을 하는 가장 손 쉬운 길은 timeServe정의 내에 있다.
timeServer = tdStart + ipAddress.setResultsName("ipAddress") + tdEnd         + tdStart + SkipTo(tdEnd).setResultsName("locn") + tdEnd
이제 for루프로 깔금하게 마무리 하고 사전에 데이터 형에 있는 한 멤버처럼 이들을 엑세스 할 수 있다.
servers = {}for srvrtokens,startloc,endloc in timeServer.scanString( serverListHTML ):    print "%(ipAddress)-15s : %(locn)s" % srvrtokens    servers[srvrtokens.ipAddress] = srvrtokens.locn
예제 5 에는 최종 실행 프로그램이 있다.

예제5
from pyparsing import *import urllib# NTP서버에 대한 기본적인 텍스트 패턴 정의 integer = Word("0123456789")ipAddress = Combine( integer + "." + integer + "." + integer + "." + integer )tdStart = Literal("<td>").suppress()tdEnd = Literal("</td>").suppress()timeServer = tdStart + ipAddress.setResultsName("ipAddress") + tdEnd +              tdStart + SkipTo(tdEnd).setResultsName("locn") + tdEnd# 타임서버 리스트 가져오기nistTimeServerURL = "http://tf.nist.gov/service/time-servers.html"serverListPage = urllib.urlopen( nistTimeServerURL )serverListHTML = serverListPage.read()serverListPage.close()servers = {}for srvrtokens,startloc,endloc in timeServer.scanString( serverListHTML ):    print "%(ipAddress)-15s : %(locn)s" % srvrtokens    servers[srvrtokens.ipAddress] = srvrtokens.locnprint servers
이제 성공적으로 NTP서버, IP주소 그리고 프로그램 변수를 성공적으로 추출해서 NTP클라이언트 프로그램은 파싱된 결과를 사용할 수 있다.

결론

Pyparisng은 재귀하향 파서를 만드는 기본적인 프레임 워크를 제공한다. 입력 문자열 스캐닝의 오버헤드 기능에 주의, 일치하는 않는 표현식 처리, 일치하는 것 중 가장 긴 것 선택하기, 콜백함수 호출, 그리고 파싱된 결과를 리턴하는 것이 이 파서의 내용에 속한다. 이로 인해 개발자는 문법 디자인과 이에 대응하는 토큰 처리 구현에만 집중할 수 있다.조합자로서의 pyparsing의 특징으로 인해 개발자는 응용프로그램을 간단한 토큰화 프로그램에서 복잡한 문법 처리기로 확장할 수 있다. 당신의 다음 파싱 프로젝트로 이를 활용하는 것은 아주 훌륭한 방법이다.

pyparsing 다운받기


저자 Paul McGuire는 Alan Weber & Associates에서 제조시스템 수석컨설턴트로 있다. 여가 시간에 SourceForge의 pyparsing프로젝트를 관리한다.

역자 참고

파싱 및 문법 구성에 대한 일반적인 내용을 참고하기 위해서는 lex와 yacc(개정판)이 많은 도움이 된다.


역자 주재경님은 현재 (주)세기미래기술에 근무하고 있으며 리눅스, 네트워크, 운영체제 및 멀티미디어 코덱에 관심을 가지고 있습니다.
* e-mail : jkjoo@segifuture.com

Copyright © 2009 Hanbit Media, Inc.

파이썬으로 재귀하향 파서 만들기(1)

제공 : 한빛 네트워크
저자 : Paul McGuire
역자 : 주재경
원문 : Building Recursive Descent Parsers with Python

파싱이란 무엇인가? 파싱이란 의미를 추출하기 위해 일련의 심벌을 처리하는 것을 말한다. 전형적으로 이것은 문장에서 단어를 읽어 이로부터 의미를 끌어내는 것을 의미한다. 응용프로그램이 텍스트로 된 데이터를 처리해야 할 때 파싱로직 형태의 뭔가를 사용해야 한다. 이 로직은 텍스트 문자와 문자 그룹(단어)를 스캔하며 정보나 명령을 추출하기 위해 문자 그룹을 인지한다.

소프트웨어 파서는 일반적으로 특정 형태의 텍스트를 처리하기 위해 만들어진 특수 목적의 프로그램이다. 이 텍스트는 보험이나 의료계에서 사용하는 알 수 없는 기호로 이루어진 문자 일수도 있고, C 헤더 파일에 있는 함수 선언, 그래프의 상호간 연결을 보여주는 node-edge에 대한 설명, 웹페이지의 HTML태그, 혹은 네트워크 설정을 위한 명령어, 3D 이미지 수정이나 회전을 위한 명령어 일 수 있다. 각각의 경우 파서는 문자 그룹과 패턴의 특정 집합을 처리한다. 이 패턴 집합을 파서의 문법이라 한다.

예를 들면, 문자 Hello, World!를 파싱할 때 일반적인 패턴을 따르는 인사말을 파싱하고 싶을 것이다. Hello, World!는 인사말 단어 Hello로 시작한다. 아주 많은 인사말이 있다. Howdy, Greetings, Aloha, G’day등. 그러므로 단지 한 단어의 인사말로 시작하기 위해서는 아주 좁은 의미의 인사말 문법을 정의 할 수 있다. 콤마 문자가 뒤에 온 다음 인사말과 인사하는 대상이 한 단어로 온다. 마지막으로 감탄부호와 같은 종료 구두점이 인사말을 끝낸다. 이 인사 문법은 대략 아래와 같다.(::는 ~로 구성되어 있다는 의미이다)
word           :: group of alphabetic characterssalutation     :: wordcomma          :: ","greetee        :: wordendPunctuation :: "!"greeting       :: salutation comma greetee endPunctuation
이것은 BNF형태이다. 기호를 표현하는 데는 아주 많은 방법이 있다.

BNF형태의 내용으로 원하는 문법을 정의 했으면 실행 가능한 형태로 이 것을 변환해야 한다. 일반적인 방법이 재귀 하향 파서를 만드는 것이다. 이 파서는 저 수준의 함수를 호출하는 고 수준의 함수와 문법의 터미널을 읽어 들이는 기능을 정의한다. 함수는 현 파싱 위치에서 일치하는 패턴이 있으면 일치하는 토큰을 리턴하고 실패하는 경우 예외를 발생시킨다.

Pyparsing이란?

Pyparsing은 재귀 하향 파서를 쉽고 빠르게 작성하도록 돕는 파이썬 클래스 라이브러리 이다. 아래에 Hello, World!보기에 대한 파싱 보기가 있다.
from pyparsing import Word, Literal, alphassalutation     = Word( alphas + "'" )comma          = Literal(",")greetee        = Word( alphas )endPunctuation = Literal("!")greeting = salutation + comma + greetee + endPunctuation
Pypasring의 여러 기능은 개발자가 텍스트 파싱 기능을 빠르게 개발하도록 돕는다.
  • 문법은 파이썬을 따른다. 그러므로 문법을 정의한 별도의 파일이 필요치 않다.
  • 추가적인 어떤 문법도 필요없다. And에 대한 +, Or에 대한 ^, 첫 매치에 대한 | 그리고 Not에 대한 ~은 예외이다.
  • 어떤 특별한 코드 생성 단계도 없다.
  • 파서 요소 사이에 나타나는 스페이스와 주석은 암묵적으로 아무 처리도 하지 않는다. 무시 가능한 텍스트에 표시를 해서 문법을 복잡하게 할 필요가 없다.
pyparsing문법은 Hello, World!뿐만 아니라 아래의 문장 중 그 어느 것도 파싱을 한다.
  • Hey, Jude!
  • Hi, Mom!
  • G'day, Mate!
  • Yo, Adrian!
  • Howdy, Pardner!
  • Whattup, Dude!
예제1은 완전한 Hello, World!파서와 파싱된 결과를 보여주고 있다.

예제 1
from pyparsing import Word, Literal, alphassalutation     = Word( alphas + "'" )comma          = Literal(",")greetee        = Word( alphas )endPunctuation = Literal("!")greeting = salutation + comma + greetee + endPunctuationtests = ("Hello, World!", "Hey, Jude!","Hi, Mom!","G'day, Mate!","Yo, Adrian!","Howdy, Pardner!","Whattup, Dude!" )for t in tests:        print t, "->", greeting.parseString(t)===========================Hello, World! -> ['Hello', ',', 'World', '!']Hey, Jude! -> ['Hey', ',', 'Jude', '!']Hi, Mom! -> ['Hi', ',', 'Mom', '!']G'day, Mate! -> ["G'day", ',', 'Mate', '!']Yo, Adrian! -> ['Yo', ',', 'Adrian', '!']Howdy, Pardner! -> ['Howdy', ',', 'Pardner', '!']Whattup, Dude! -> ['Whattup', ',', 'Dude', '!']
Pyparsing은 조합자(Combinator)이다

pyparsing모듈로 먼저 문법의 기본적인 것들을 정의한다. 그 다음 전체 문법 문장에 대한 다양한 분기를 위해 좀더 복잡한 파서 표현으로 이것들을 조합한다. 다음과 같이 관계를 정의하여 이것들을 조합한다.
  • 문법 내에서 어떤 표현이 뒤 따라야 하는가? 예를 들면 키워드 if 다음에는 괄호로 묶여진 불리언 표현식이 뒤 따른다.
  • 문법 내에서 어떤 표현이 특정 지점에서 올바른 대체표현인가? 예를 들면 SQL 명령어는 SELECT, INSERT, UPDATE, 혹은 DELETE로 시작할 수 있다.
  • 어떤 표현이 선택적인 표현인가? 예를 들면 전화번호는 선택적으로 괄호로 된 지역번호 뒤에 올 수 있다.
  • 어떤 표현이 반복적인가? 예를 들면 XML태그는 0혹은 그 이상의 속성을 가질 수 있다.
복잡한 문법이 수십 개 혹은 수백 개의 문법 조합을 포함하고 있다 할지라도 대부분의 파싱은 단지 몇 개의 정의로 쉽게 수행된다. 생각을 조직화 하고 파서를 디자인 하는데 BNF형태로 문법을 기술하는 것이 도움이 된다. 이것은 또한 pyparing의 함수와 클래스로 문법을 구현하는 당신의 작업을 추적하는 데도 도움을 준다.

간단한 문법 정의하기

대부분의 문법 중 가장 작은 부분을 차지하는 것은 전형적으로 문자열에 대한 정확한 매칭이다. 아래에 전화번호 파싱을 위한 간단한 BNF가 있다.
number      :: '0'.. '9'*phoneNumber :: [ '(' number ')' ] number '-' number
이것은 전화번화 내에서 괄호와 대시(-)를 찾기 때문에 이 구두점 표시를 위해 간단한 토큰을 정의 할 수 있다.
dash   = Literal( "-" )lparen = Literal( "(" )rparen = Literal( ")" )
전화번호 내에서 숫자를 정의하기 위해서 다양한 길이의 문자열을 처리할 필요가 있다. 이를 위해서는 Word토큰을 사용하라
digits = "0123456789"number = Word( digits )
숫자 토큰은 숫자로 나열되는 문자로 구성된 연속된 열과 일치할 것이다. 즉 이것은 숫자로 구성된 단어이다.(알파벳으로 구성되는 전형적인 단어와는 반대로) 이제 전화번호에 대한 각각의 문자열을 얻었으므로 이제 And 클래스를 사용하여 이것들을 문자열로 만들 수 있다.
phoneNumber =     And( [ lparen, number, rparen, number, dash, number ] )
이것은 읽기에 자연스럽지 않다. 다행히도 pyparsing모듈은 좀더 쉽게 각 파서 요소를 조합하기 위한 연산자 메서드를 정의한다. 좀더 읽기 쉬운 정의는 And를 위해 +를 사용한다.
phoneNumber = lparen + number + rparen + number + dash + number
좀더 쉽게 하기 위해 +연산자는 묵시적으로 문자 그대로 변환되는 파서 요소와 문자를 묶는다. 이것이 읽기에 더 쉽다.
phoneNumber = "(" + number + ")" + number + "-" + number
최종적으로 전화번호의 첫 부분에 지역 번호가 선택적임을 나타내기 위해 pyparsing의 Optional클래스를 사용한다.
phoneNumber = Optional( "(" + number + ")" ) + number + "-" + number
문법 사용하기

문법을 정의한 후 다음 단계는 파싱할 텍스트에 적용하는 것이다. pyparsing표현은 주어진 문법으로 입력 텍스트를 처리하기 위해 3가지의 메서드를 지원한다.
  • parseString은 입력 문자열의 내용을 판독하고 문자열을 파싱하고, 그리고 각 문법 구조에 대한 하위 문자열과 문자열의 조합을 리턴하는 문법을 사용한다.
  • scanString은 단지 입력 문자열과 일치할 수 있는 문법을 사용하며 이 문법은 일치 검사를 위해 문자열을 스캔하고 입력 문자열 내에 시작점과 마지막 지점 그리고 일치된 토큰을 포함하는 튜플을 리턴한다.
  • transformStirng은 scanString의 변종이다. 이것은 일치할 때 마다 수정되는 일치한 토큰의 변화에 대응하며 최초 입력 텍스트가 표현하는 하나의 문자열을 리턴한다.
Hello, World!파서는 parseString을 호출하고 바로 파싱된 결과인 토큰을 리턴한다.
Hello, World! -> ['Hello', ',', 'World', '!']
비록 이것이 토큰 문자열의 간단한 리스트로 보이긴 하지만 pyparsing은 ParseResults 오브젝트를 사용하여 데이터를 리턴한다. 위 예제에서 결과 값들은 파이썬의 리스트 데이터처럼 보인다. 사실 리스트 데이터처럼 단지 결과에 순서를 붙일 수도 있다.
print results[0]print results[-2]
는 다음과 같이 나타난다.
HelloWorld
parseResult를 이용하여 각 문장에 이름을 정의할 수도 있다. 이것은 파싱된 텍스트와 비트열을 반복적으로 검사하는 것을 더욱 쉽게 해 준다. 이것은 특히 문법이 선택적인 부분을 포함하고 있을 때 유용하다. 이 문법은 리턴된 토큰 리스트의 길이와 오프셋을 변경할 수 있다.
salute  = Word( alphas+"'" ).setResultsName("salute")greetee = Word( alphas ).setResultsName("greetee")
마치 리턴된 결과의 속성인 것처럼 대응되는 토큰을 참조할 수 있다.
print hello, "->", results    print results.saluteprint results.greetee
위의 내용은 다음과 같이 나타난다.
G'day, Mate! -> ["G'day", ',', 'Mate', '!']G'dayMate
위 결과는 당신이 작성한 파싱 프로그램의 가독성과 유지 보수성을 향상 시키는데 커다란 도움을 준다.

전화번호 문법의 경우 차례대로 전화번호 리스트를 가지고 있는 입력 문자열을 파싱한다. 다음과 같다.
phoneNumberList = OneOrMore( phoneNumber )data            = phoneNumberList.parseString( inputString )
이것은 pyparsing의 ParseResult 오브젝트 형태로 데이터를 리턴할 것이고 이 오브젝트는 입력 전화번호의 모든 리스트를 가지고 있다.

Pyparsing은 delimitedList와 같은 유용한 표현을 가지고 있으며 입력이 콤마로 구분되는 전화번호 리스트인 경우 간단하게 phoneNumberList를 다음과 같이 변경할 수 있다
phoneNumberList = delimitedList( phoneNumber )
이것은 전과 같은 전화번호 리스트를 리턴한다. dellimiteList는 모든 표현식과 문자열을 지원한다. 콤마 구분자가 가장 일반적이어서 기본으로 사용된다.

단지 전화번호만 가지고 있는 문자열 대신 우편번호, 주소, 메일주소, 전화번호를 가지고 있는 경우 scanString을 사용하는 전화번호로 확장해야 한다. scanString은 파이썬 생성 함수이며 for 루프, 리스트 , 생성 표현식 내에서 이것을 사용해야 한다.
for data,dataStart,dataEnd in     phoneNumber.scanString( mailingListText ):    .    .    # 전화번호 토큰으로 뭔가를 한다,     # data변수에 리턴된다    .    .
마지막으로 같은 메일링 리스트를 가지고는 있지만 잠재저인 전화 판매원으로부터 전화번호를 숨기고자 하는 경우 모든 전화번호를 (000)000-0000문자열로 변환하는 파서 동작을 추가하여 문자열을 변환 할 수 있다.
phoneNumber.setParseAction( replaceWith("(000)000-0000") )sanitizedList =     phoneNumber.transformString( originalMailingListText )
적절한 입력에 대한 동작이 정의 되지 않은 경우

Pyparsing은 주어진 파서 요소에 대해 일치하는 텍스트가 없어질 때까지 입력을 처리한다. 예상치 못한 토큰이나 문자를 만나고 이에 적절한 처리가 없는 경우 pyparsing은 parseException을 발생 시킨다. parseException은 기본으로 진단 메시지를 출력하며 이 메시지에는 라인번호, 칼럼, 텍스트 라인과 주석문이 포함된다.

파서에 Hello, World?라는 문장이 입력되는 경우 다음과 같은 예외를 만나게 된다.
pyparsing.ParseException: Expected "!" (at char 12), (line:1, col:13)
이를 바탕으로 입력문자열을 수정하거나 문장에 대해 좀더 관대한 문법을 작성할 수 있다. 위의 경우에 올바른 문장 종결자로 물음표를 지원하면 된다.


역자 주재경님은 현재 (주)세기미래기술에 근무하고 있으며 리눅스, 네트워크, 운영체제 및 멀티미디어 코덱에 관심을 가지고 있습니다.
* e-mail : jkjoo@segifuture.com

Copyright © 2009 Hanbit Media, Inc.


//파일 읽기
private void FileRead(params string[] UserInfo)
{
FileStream fs = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.Read);
StreamReader st = new StreamReader(fs, System.Text.Encoding.UTF8);

st.BaseStream.Seek(0, SeekOrigin.Begin);

while (st.Peek() > -1)
{
stringtemp = st.ReadLine();
//MessageBox.Show(aaa);
}
st.Close();
fs.Close();
}

//파일쓰기

private void FileWrite(string str)
{
FileStream fs = new FileStream(FileName, FileMode.Append, FileAccess.Write);
//FileMode중 append는 이어쓰기. 파일이 없으면 만든다.

StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8);
sw.WriteLine(str);
sw.Flush();
sw.Close();
fs.Close();
}

리눅스 시스템 시간동기화 하기 ( rdate, ntp )

시간동기화에 대해서 가끔 중요성을 상실할때가 너무많다.
심하게 둔한 관리자는 몇주, 몇달후 날짜가 안맞다는 고객의 제보로 수정 경우도...
저같은 경우는 시스템 설치직후 이 작업부터 시행합니다 ^^;


1. rdate 를 이용한 동기화
- 레드햇계열 및 여타 배포판에서도 별도의 설치과정필요없이 사용할수있다.
쉘스크립파일을 하나 작성한다.

ex) time-sync.cron ---------------------------
#!/bin/bash
/usr/bin/rdate -s time.bora.net && /sbin/clock -w
---------------------------------------------

저장후 실행권한 부여
#chmod 755 time-sync.cron

작성한 파일을 /etc/cron.daily 로 복사 ( 일일 새벽 4시에 동기화 스크립트를 수행함 )

2. ntp 를 이용한 동기화

- rdate 를 이용한 방법보다 소수점 몇몇점이하까지 상세히 동기화해준다고해서 애용중;

#rpm -qa | grep ntp 명령으로 "ntp-버젼" 이 출력되지않으면
http://rpmfind.net 에서 "ntp" 로 검색해서 배포판에 해당하는 패키지를 설치한다

ex1)
OS : Fedora Core 3
#wget ftp://rpmfind.net/linux/fedora/core/3/i386/os/Fedora/RPMS/ntp-4.2.0.a.20040617-4.i386.rpm

ex2)
#rpm -Uvh ftp://rpmfind.net/linux/fedora/core/3/i386/os/Fedora/RPMS/ntp-4.2.0.a.20040617-4.i386.rpm


- 동기화
  #ntpdate -b -s time.kriss.re.kr
  // -s : 결과를 화면이 아닌 syslog 로 보냄

* 다음과 같은 오류가 발생한 경우
 [root@truefeel root]# ntpdate -b time.kriss.re.kr
 17 Mar 21:03:25 ntpdate[8244]: no server suitable for synchronization found


 -> NTP 프로토콜은 UDP port 123 을 사용하는데, 이 포트가 방화벽 등으로
    막혀있는 경우에는

    #ntpdate -u time.kriss.re.kr

    처럼 -u 를 옵션을 사용해서 다른 포트 사용하거나
IPTABLE 을 사용중이면 OUTBOUNT UDP 123 포트를 열어준다

- cron.daily 에 등록 ( 쉘스크립트 파일 작성 )
ex) time-sync.ntp ---------------------------
#!/bin/bash
/usr/sbin/ntpdate -b -s time.kriss.re.kr && /sbin/clock -w
---------------------------------------------

저장후 실행권한 부여
#chmod 755 time-sync.ntp

작성한 파일을 /etc/cron.daily 로 복사 ( 일일 새벽 4시에 동기화 스크립트를 수행함 )

Posted

리눅스의 배포판확인, 커널버전 확인 방법


강사 : 박성수 (papa@superuser.co.kr)

리눅스의 배포판버전, 커널버전확인방법

1. 개론

별것 아닌 것 같지만, 리눅스를 처음사용하거나 초보자인경우에는 리눅스의 버전확인하는 방법이 애매할때가 있다.

물론, 자기자신이 설치한 경우에는 기억을 하고 있어서 알겠지만 설치한 기간이 꽤오래된 경우에는 가끔씩 헷갈릴때가 있다.

리눅스설치를 6.0으로 했는지 6.1, 6.2로 했는지 또는 7.0으로 했는지 7.1로 했는지,

그리고 커널버전이 정확히 어떻게 되는지등에 관해서 정확한 버전확인을 원한다면 아래를 참조하기 바란다.

2. 배포판 버전확인

/etc/ 디렉토리에 보면 redhat-release라는 파일이 있다. 이 파일내용에는 배포판의 이름과 버전정보가 있다.

물론, 누군가 수정했다면 이 정보는 신뢰하기 힘들겠지만, 어쨌든 이 정보를 이용하여 배포판의 버전을 확인할수 있다.

3. 커널버전확인

리눅스의 커널버전확인은 간단히 uname -a 로 하면 알수 있다.

4. 리눅스 설치 module 정보확인

리눅스박스에 설치된 모듈에 대한 구체적인 파일내역을 확인하려면 아래예와 같이 /lib/modules 디렉토리를 참조하기 바란다.

5. 설치패키지 전체확인

참고로 rpm 명령어를 이용하여 설치된 패키지를 차근차근 살펴보려면 "rpm -qa | more"로 살펴보면 된다.

6. 특정 설치패키지 확인

아래와 같이 "rpm -qa | grep 패키지명"으로 특정 패키지의 설치여부를 확인할수 있다.

7. 초기 설치 패키지 정보확인

/tmp/install.log 파일을 보면 리눅스설치초기시에 설치된 패키지이름들이 들어가 있다.

이 파일도 함께 참조하면 좋을 것 같아서 언급하여본다.

'기본 카테고리' 카테고리의 다른 글

C# (CSharp) 파일 입출력  (0) 2009.02.27
리눅스 시스템 시간동기화 하기 ( ntp, rdate )  (0) 2009.02.23
m480  (0) 2009.02.19
MySQL 날짜 시간 함수  (0) 2009.02.18
Compressing and DeCompressing a File in C#  (0) 2009.02.18

카페 TIP게시판의 게시물 중에 (질문/사용설명서에 포함된 내용/ 검증되지 않은 내용/프로그램게시)이 포함된 내용은 목록에 정리 되어있지 않습니다.실수로 일부 내용이 빠질 수도 있습니다.

게시판에 게시물들 읽다가 눈에 띄는 게시물들만 골라 봤습니다.

1. 여러 버그와 프로그램 충돌로 고생하시는 분들에게 -스티커님

2.

3. 미라지 활용방법 AE Button+FTouchSL+780 Cursor조합) -제이대디님

4. 레지수정을 통한 미라지 각종 사운드무음화 하기(게시물 내용은 I780/ 댓글을 참고)

5. mp3/wma/mmf벨소리 설정하기

6. 삼성 ANYCALL A/S 문의 바로가기 주소링크

7. 초기 미라지 응답 속도 높이는 방법

9. 터치스크린 향상 레지스트리 수정방법

10. 은디아예님의 미라지 쿼티 완전정복하기

11. nodata필요없는 3G차단 방법

12. 은디아예님의 배터리 체감 사용시간 늘리기

13. 공대생님의 PDA처음 사용자만 보세요.

14. 은디아예님의 수동 펌업하기

15. WYZ070하기(WM6.1 VOIP용)

16. NET1000 입/해지 카페

요금제/가입/번호 변경<?xml:namespace prefix = o />

1. SKT

1. 신규 가입후 변호변경 방법

2. SKT번호 이동 3개월 이내시 무료문자 150

3. 커피N무비 무한벨 정액제

4. SKT e-mail 서비스

5. 114통한 요금제 해지 예약 방법

6. E-mail 3000 해지하기

미라지 사용기

SKT용 미라지(M480)

KTF용 미라지(M4800)

1. 두끄님의 미라지 활용기(동영상)

2. JUNOWEB님의 프로그램 설치기

3. 동해랑님의 어플 설치 사용기/2

1. capdw126 님의 사용기

2. kirinsunflow 사용기

미라지 H/W /롬업데이트

  1. 키패드

  2. 배터리

    1. 대용량 배터리 사용하기

  3. 충전기 관련

    1. 충전케이블 제작

      1. 우지니님

  4. 터치스크린

  5. 교통카드 심기

  6. 롬 업데이트

  7. USIM문제

연락처

초기부팅/프로그램 일반/레지스트리 수정관련/백업

1. 버그

2. 리어 하기

3. 보기 변경안될

4. 리기

5. 초기 미지

6. 스트

7. 비설치 유틸의 바로가기 설정 레지스트리 수정/ 메일 설정방법

8. OK버튼의 사용법

9. SKT

10. 초기 부팅시 CPROG.EXE.에러

1.

Activesync/WMDC 6.1

  1. WMDC (VISTA 유저)

  2. Activesync

    1. 이동식 디스크로 결하기 (빠른 파일이동)

    2. USB연결을 이용한 인터넷 안될 때

    3. 에러코드별 분류

      1. 80070490오류

      2. 86000107오류

    4. 블루투스 연결

1. 블루투스를 통한 activesync 연결 안될때

2. BLUESOLEIL 블루투스 연결하기

3. 블루투스로 HSDPA연결하여 인터넷 하기

4. ACTIVEYSN파트너 설정 오류 해결

5. 루투

미라지튠 관련

내부 메모리 확보 및 외장메모리

1. 내부메모리

1. OPERA 브라우져 삭제로 내부 메모리 확보하기

2. 미라지용 설치 프로그램 메모리 점유량 v1.1 (아웃룩 싱크, 펌업 초기 메모리 정보 포함)

3.

2. 외장 메모리

1. SDHC.CAB 패치 설치 안될

무선랜/3G연결

  1. 무선랜

    1. NESPOT

  2. 3G연결

문자 /메일

  1. 문자 프로그램

    1. 해외문자 보내기(ms-sms)

    2. 특정위치에 문자 바로보기

  2. 메일(OUTLOOK)

키패드/입출력 TIP

1. 한영 입력상태창 표시하기

2. I780에서 한글 입출력 하기

3. 미라지에서 천지인,모아키,디오펜 사용시 쌍받침 문제 해결방법

4. 은디아예님의 미라지 쿼티 완전정복하기 (강추 꼭 읽어보세요)

1. 네입어님의 특수문자를 제외한 방향키 맵핑

5. SORTINCHKEY

1. SORTINCHKEY 이용한 멀티기능 HOT KEY만들기

벨소리/모닝콜/알람/프로필

1. 모닝콜 /알람

1. 내장 모닝콜/알람음 변경하기

2. 모닝콜 버그 패치

2. 벨소리

1. mp3/wma/mmf벨소리 설정하기

2. 하게 MP3벨/ 하기

3. 프로필

1. 매너모드시 진동이 느껴지지 않는 현상시 체크사항

카메라

1. 카메라 셔터음무음화 하기

2. 접사를 위한 휴대용 렌즈 추천

l 돋보기를 이용한 접사

3. 미라지 카메를 자동차용 전방 감시 카메라로 이용하

투데이 꾸미기

1. WISBAR ADVANCE DESKTOP(WAD)

1. WAD에서 날씨 보이게 하기

2. 나두님의 WAD이용 홈스크린 만들기

1. (강좌1 /강좌2 )

2. ULTIMATE LAUNHER

      1. 메이탄님의 네입어님 홈스크린 무작정 따라하기

        1. (강좌 1 /강좌2 /강좌3 /강좌4)

      2. 조팀님의 UL용 아이콘 만들기 강좌

        1. (강좌1) / (강좌2) / (강좌 3)

      3. 슈드님의 UL테마 만들기 강좌

        1. (강좌1) / (강좌 2)

3. SPB MOBILE SHELL

      1. 96DPI 테마

      2. 128DPI 테마

      3. 기타

        1. 와 SMS 하기 (구버젼)

        2. 문자 메시지 (구버젼)

        3. SPB MOBILE SHELL테마 안내 스키너 찾기 (하위 게시물 참고바람/다양한 테마안내)

  1. HS++UI를 이용한 테마 만들기

· XML 좌표에 관하여

· 주요 참고 레지스트리

· 푸른하늘님의 HS++ 강좌

· 96DPI용

o 조팀님의 미라지 테마(2008/09/23 버전)

o 조팀님의 미라지 테마(2008/09/11 버전)

o 아인스님의 다이아 몬드 shell버젼-수정:IKJsoft (파일은 답글참고)

1. 128DPI용

1. 조팀님의 미라지 테마 128 DPI 수정- 보명님(2008/09/23 버젼)

2. 조팀님의 미라지 테마 128 DPI 수정- 보명님(2008/09/11 버전) -XML파일외 기타 파일은 96DPI사용

3. 아인스님의 다이아 몬드 Shell버젼 -수정:갓위더스님

1. 제작 강좌 (4650카페/아인스님 블로그 링크 참고하세요)

5. 기타

    1. 바로가기 아이콘 만들기

동영상

1. 인코딩

1. 곰인코더 사용하기

2. Windows Media Encoder 사용하기

원격조정

1. PDA TO PC

1. Z2RemotetoPC

2. ORB.COM

        1. 무선인터넷을 이용한 외부에서 컴에 있는 동영상등을 감상하기

프로그램별 강좌 및 사용 TIP (ABC)

    1. 미라지 덤프툴(건달님)

    2. CAB VIA ACTIVESYNC(CAB파일 바로 설치 하는 프로그램)

    3. fn런쳔(기본프로그램)

    4. FRING

    5. Google Application

      1. Google Map

      2. Gmail

      3. Google calendar

    6. INTERNET EXPLOERER

    7. MAGICCALL

    8. MEMMAID

    9. MORTSCRIPT

    10. OPERA MINI

      1. OPERA MINI하기 (하위 답글 확인하세요)

    11. POCKET ARTIST 3

      1. (강좌 1 /강좌2)-나화사님

      2. 강좌 가기은디아예님

    12. POCKET MUSIC 5.1

    13. REAL VGA(96DPI)

    14. SCREEN CAPTURE

      1. 미라지폰 화면 캡춰하기(FREE WARE)

    15. SPB프로그램

      1. SPB DIARY

      2. SPB PHONE SUITE

      3. SPB POCKETPLUS

      4. SPB WEATHER

    16. SYSNC MAIL

    17. S2U2

    18. TCPMP

    19. TOMBO (다단계 메모프로그램)

      1. cplusman75님의 강좌

    20. TOTAL VIEWER

    21. VITO AUDIO NOTES 1.32

      1. 강좌 1나화사님

    22. WINDOWS MEDIA PLAYER

    23. WISBAR ADVACE

    24. WINTERFACE

    25. WMWIFIROUTER(3g연결을 이용 미라지를 AP처럼 사용)

      1. 강좌1- 나화사님

    26. XYVIEW

      1. 자이뷰/ 미라지로 보안감시 활용하기

PDA용 웹 사이트

1. 목록 작성자: 시화님

2. Tstory 모바일 사이트 이용방법

3. 미라지에서 버스도착시간 알림 사이트 활용방법

4. 네츠님의 모바일로 시작페이지

[날짜/시간 함수] MySQL Database - Oracle

2004/07/09 16:21

복사 http://blog.naver.com/ddor77/60003904989

[날짜/시간 함수]

(1) 날짜/시간 1

1) NOW() : 오늘의 날짜와 현재 시간을 'YYYY-MM-DD HH:MM:SS' 혹은 'YYYYMMDDHHMMSS' 형식으로 나타냅니다.

2) CURDATE() : 'YYYY-MM-DD' 혹은 'YYYYMMDD' 형식으로 오늘 날짜를 나타냅니다.

3) CURTIME() : 'HH:MM:SS' 또는 'HHMMSS' 형식으로 현재 시간을 나타냅니다.

예제 1

mysql> select NOW(); // *1
mysql> select CURDATE(); // *2

mysql> select CURTIME(); // *3

*1 현재 날짜와 시간을 조회합니다.
*2 현재 날짜를 조회합니다.

*3 현재 시간을 조회합니다.

(2) 날짜/시간 2

1) DAYOFWEEK(date) : 날짜를 몇 번째 요일인지 숫자로 나타냅니다. 숫자 '1'은 일요일, '2'는 월요일, ... '7'은 토요일입니다.

2) DAYOFMONTH(date) : 날짜를 그 달의 몇 번째 날인지 나타냅니다. 반환값은 1 에서 31 입니다.

3) DAYOFYEAR(date) : 날짜를 한 해의 몇 번째 날인지 나타냅니다. 반환값은 1 에서 366 까지입니다.

예제 2

mysql> select DAYOFWEEK('2002-03-01'); // *1
mysql> select DAYOFMONTH('2002-03-01'); // *2

mysql> select DAYOFYEAR('2002-03-01'); // *3

1* 2002년 3월 1일은 금요일이므로 결과값은 6 을 반환합니다.
2* 2002년 3월 1일은 3월의 첫째날이므로 1 을 반환합니다.
3* 2002년 3월 1일은 1월 1일 이후 60 날이므로 60 을 반환합니다.

(3) 날짜/시간 3

1) MONTH(date) : 해당 날짜가 몇 월인지 나타냅니다. 반환값은 1 ~ 12 입니다.

2) DAYNAME(date) : 해당 날짜의 요일을 영어로 나타냅니다.

3) MONTHNAME(date) : 해당 날짜의 월 이름을 영어로 나타냅니다.

예제 3

mysql> select MONTH('2002-03-01'); // *1
mysql> select DAYNAME('2002-03-01'); // *2

mysql> select MONTHNAME('2002-03-01'); // *3

*1 2002년 3월 1일은 3월이므로 결과값 3 을 반환합니다.
*2 2002년 3월 1일은 금요일이므로 결과값 Friday 를 반환합니다.
*3 2002년 3월 1일은 3월이므로 결과값 March 를 반환합니다.

(4) 날짜/시간 4

1) HOUR(time) : 시간을 나타냅니다. 반환값은 0 ~ 23 입니다.

2) MINUTE(time) : 분을 나타냅니다. 반환값은 0 ~ 59 입니다.

3) SECOND(time) : 초를 나타냅니다. 반환값은 0 ~ 59 입니다.

예제 4

mysql> select HOUR(now()); // *1
mysql> select MINUTE(now()); // *2

mysql> select SECOND(now()); // *3

*1 현재 시간의 시(HOUR)를 반환합니다.
*2 현재 시간의 분(MINUTE)를 반환합니다.
*3 현재 시간의 초(SECOND)를 반환합니다.

'기본 카테고리' 카테고리의 다른 글

리눅스의 배포판확인, 커널버전 확인 방법  (0) 2009.02.23
m480  (0) 2009.02.19
Compressing and DeCompressing a File in C#  (0) 2009.02.18
Writing an ActiveX control in C#  (0) 2009.02.17
ClickOnce Deployment Limitations  (0) 2009.02.09

MySQL 함수 2-1 날짜 및 시간 관련 칼럼 함수 첫번째

아노..함수 입니다..

갠적으로 싫어하는 게 함수라..

양은 양대로 많고..이해한다고 해도..

놓치지 쉬운 부분이라..

실제로 사용하는 거 몇가지 빼고는..

거의 모르고 살게 되지요..

예전 웹마스터 교육 받고..

그 당시 인기던..

pure lite dream 아이콘 방명록..

이름이 맞나 모르겠네..

그거 제작자한테 허락맞고 cgi 였던거를

php 로 컨버팅한적 있는데..

웹프로그래밍 만들때는 MySQL 보다 php 함수가 더 큰 영향을 받아서..

MySQL 기분 문법 select insert update delete 밖에 안 썻었지..

지금 보니..

최종 수정 시간 입력할때..

단지..MySQL 함수 하나로 끝날 수 있었네..

php 로 할때..

일일히 시간 구해서 업데이트 방식 썻었는데..

머 이로서..

짜기전에 함수 한번 정도 알아 두면 좋다 ㅇㅅㅇ

라는 거지요..

그럼 시작 하겠습니다.

----------------------------------------------------------------------------------------

- 날짜 및 시간 관련 함수

날짜 시간 관련 칼럼 타입

- 날짜 관련 타입은 문자 칼럼 타입 (char, varchar 등), 숫자 칼럼 타입 (int, smallint 등)

- 과 함깨 가장 많이 사용되는 칼럼이다.

- DATE

- 날짜 타입이다. '1000 - 01 - 01' 에서 '9999 - 12 - 31' 까지 나타낼 수 있다.

- 기본적으로 지원 하는 형태는 'YYYY - MM - DD' 이다.

- DATETIME

- 날짜와 시간이 합쳐진 형태이다. '1000 - 01 - 01 00:00:00' 에서 '9999 - 12 - 31 23:59:59'

- 까지 나타낼 수 있다.

- 기본적으로 지원하는 형태는 'YYYY - MM - DD HH:MM:SS' 이다.

- TIMESTAMP[(M)]

- 날짜 및 시간 타입이다. '1970 - 01 - 01 00:00:00' 에서 2037 년 어느 때까지 나타낸다.

- [(M)] 자리에는 출력될 길이를 나타내는 숫자를 쓸 수 있는데 14 나 12 나 8 혹은 6 을

- 쓸수 있다. 숫자를 쓰지 않으면 기본적으로 14 자리로 나타낸다.

- TIMESTAMP 의 특징은 자동 변경 칼럼 타입이라는 것이다. 이것은 INSERT 나 UPDATE

- 문을 사용할때 매우 유용하다.

mysql> desc customers;
+--------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------+------+-----+---------+----------------+
| customers_id | int(5) | | PRI | NULL | auto_increment |
| gender | char(1) | | | | |
| name | varchar(32) | | | | |
| job | varchar(30) | | | | |
| email | varchar(35) | | | | |
| address | varchar(100) | | | | |
| telephone | varchar(14) | | | | |
| registdate | date | YES | | NULL | |
| modifydate | timestamp(14) | YES | | NULL | |
| password | varchar(12) | | | | |
+--------------+---------------+------+-----+---------+----------------+
10 rows in set (0.06 sec)

mysql>

- 현재 customers 테이블의 modifydate 칼럼은 TIMESTAMP(14) 로 정의되어 있다.

mysql> select name, telephone, modifydate from customers where name = '장영실';
+--------+--------------+----------------+
| name | telephone | modifydate |
+--------+--------------+----------------+
| 장영실 | 051-665-6789 | 20020903162508 |
+--------+--------------+----------------+
1 row in set (0.00 sec)

mysql>

- 장영실 이라는 고객에 대해 다음과 같은 데이터가 들어있다.

mysql> update customers set telephone = '051-665-1234' where name = '장영실';
Query OK, 1 row affected (0.45 sec)
일치하는 Rows : 1개 변경됨: 1개 경고: 0개

- 위와 같이 '장영실' 의 전화번호를 update 문으로 변경하여 보다.

mysql> select name, telephone, modifydate from customers where name = '장영실';
+--------+--------------+----------------+
| name | telephone | modifydate |
+--------+--------------+----------------+
| 장영실 | 051-665-1234 | 20061005162108 |
+--------+--------------+----------------+
1 row in set (0.00 sec)

mysql>

- 전화번호만 변경 했음에도 불구하고 자동으로 modifydate 칼럼의 값도 현재 날짜로

- 변경되는 것을 볼 수 있다. 즉 TIMESTAMP 칼럼은 데이터가 수정된 날짜를

- 자동으로 체크하는데 유용하게 사용할 수 있는 칼럼이다.

- TIME

- 시간 타입니다. '-838:59:59' 에서 '838:59:59' 까지 나타낼 수 있다.

- 기본적으로 지원하는 형태는 'HH:MM:SS' 이다.

- YEAR

- 연도를 나타내는 타입이다. 2자리 혹은 4자리로 나타낼 수 있으며 자리수를 정하지 않으면

- 기본적으로 4자리로 나타낸다. 4자리로 사용할 때는 1901에서 2155년까지 지원하며

- 2자리로 사용할 때는 1970에서 2069년짜지 지원한다. (70-69)

- 위의 것은 칼럼을 생성할 때 옵션 문으로 들어 간다.

날짜 및 시간 관련 함수

- MySQL 에서는 날짜 및 시간 관련하여 매우 다양하고 유용한 함수들을 지원한다.

mysql> select name, modifydate from customers;
+----------+----------------+
| name | modifydate |
+----------+----------------+
| 방정환 | 20020213150234 |
| 한용운 | 20011124201452 |
| 김정호 | 20011124230126 |
| 허난설헌 | 20000305092412 |
| 우장춘 | 20020312183521 |
| 장영실 | 20061005162108 |
| 안익태 | 20010824010354 |
| 신사임당 | 20020317224541 |
| 허준 | 20020816175657 |
| 황진이 | 20011230204703 |
+----------+----------------+
10 rows in set (0.00 sec)

mysql>

- 다음 예는 customers 테이블로부터 지난 30일간 변경된 적이 있는 로우룰 추출하는 예이다.

mysql> select name, modifydate from customers where to_days(now()) - to_days(modifydate) <= 30;
+--------+----------------+
| name | modifydate |
+--------+----------------+
| 장영실 | 20061005162108 |
+--------+----------------+
1 row in set (0.47 sec)

mysql>

- 지금부터 TO_DAYS(), NOW() 와 같은 날짜 및 시간 관련 함수들을 하나씩 알아 보겠다.

- to_days(now()) - to_days(modifydate) <= 30;

- 현재 날짜 시간 - 각 로우의 최종수정된 시간 의 값이 30 보다 적을 것 을 나타냄

- DAYOFWEEK(date)

- 지정한 날짜가 그 주의 몇번째 요일인가를 가져온다.(1=일요일, 2=월요일, ... 7=토요일)

- 2006년 10월 5일은 목요일이므로 5번째 요일이다.

mysql> select dayofweek('2006-10-5');
+------------------------+
| dayofweek('2006-10-5') |
+------------------------+
| 5 |
+------------------------+
1 row in set (0.00 sec)

mysql>

- WEEKDAY(date)

- DAYOFWEEK(date) 와 같으나 0은 월요일, 1은 화요일 ... 6은 일요일을 의미한다.

mysql> select weekday('2006-10-5');
+----------------------+
| weekday('2006-10-5') |
+----------------------+
| 3 |
+----------------------+
1 row in set (0.00 sec)

mysql>


- DAYOFMONTH(date)

- 1에서 31까지 중 해당 달의 몇번째 날인지를 가져온다.

mysql> select dayofmonth('2006-10-5');
+-------------------------+
| dayofmonth('2006-10-5') |
+-------------------------+
| 5 |
+-------------------------+
1 row in set (0.00 sec)

mysql>

- DAYOFYEAR(date)

- 1에서 366까지 중 해당 연도의 몇번째 날인지를 가져온다.

mysql> select dayofyear('2006-10-5');
+------------------------+
| dayofyear('2006-10-5') |
+------------------------+
| 278 |
+------------------------+
1 row in set (0.00 sec)

mysql>

- MONTH(date)

- 1에서 12까지 중 해당 연도의 몇번째 달인지를 가져온다.

mysql> select month('2006-10-5');
+--------------------+
| month('2006-10-5') |
+--------------------+
| 10 |
+--------------------+
1 row in set (0.00 sec)

mysql>


- DAYNAME(date)

- 해당 날짜의 요일명을 가져온다.

mysql> select dayname('2006-10-5');
+----------------------+
| dayname('2006-10-5') |
+----------------------+
| Thursday |
+----------------------+
1 row in set (0.00 sec)

mysql>


- MONTHNAME(date)

- 해당 달의 이름을 가져온다.

mysql> select monthname('2006-10-5');
+------------------------+
| monthname('2006-10-5') |
+------------------------+
| October |
+------------------------+
1 row in set (0.00 sec)

mysql>

- QUARTER(date)

- 분기를 계산할 때 유용한 함수이다.

- 1년을 4분기로 나누어 1에서 4까지 중 해당 분기를 가져온다.

mysql> select quarter('2006-10-5');
+----------------------+
| quarter('2006-10-5') |
+----------------------+
| 4 |
+----------------------+
1 row in set (0.00 sec)

mysql>

- WEEK(date)

- 해당연도의 몇번째 주인가를 가져온다.

mysql> select week('2006-10-5');
+-------------------+
| week('2006-10-5') |
+-------------------+
| 40 |
+-------------------+
1 row in set (0.00 sec)

mysql>

- WEEK(date,first)

- week(date) 와 동일하나 한 주의 기준을 정할 수 있다.

- first 인자에 0을 쓰면 일요일로 시작되는 주를 기준으로 순서를 가져오며

- 1을 쓰면 월요일로 시작되는 주를 기준으로 순서를 가져온다.

- MySQL 4.0 에서 first 에 해당하는 인자가 0 이고 해당 날짜가 전년도의 마지막 주에 해당

- 하면 0을 가져온다.

mysql> select week('2006-01-01'), week('2006-01-01',1), week('2006-01-01',0);
+--------------------+----------------------+----------------------+
| week('2006-01-01') | week('2006-01-01',1) | week('2006-01-01',0) |
+--------------------+----------------------+----------------------+
| 1 | 0 | 1 |
+--------------------+----------------------+----------------------+
1 row in set (0.00 sec)

mysql>

- YEAR(date)

- 1000 에서 9999 까지의 연도를 가져온다.

mysql> select year('2006-10-5');
+-------------------+
| year('2006-10-5') |
+-------------------+
| 2006 |
+-------------------+
1 row in set (0.00 sec)

mysql>

- YEARWEEK(date)

- 연도와 몇번째 주인가를 동시에 가져온다.

mysql> select yearweek('2006-10-5');
+-----------------------+
| yearweek('2006-10-5') |
+-----------------------+
| 200640 |
+-----------------------+
1 row in set (0.00 sec)

mysql>

- YEARWEEK(date,first)

- yearweek(date) 와 동일하며 week(date,first) 에서 처럼 first에 한 주의 기준을

- 정할 수 있다. first에 해당하는 인자가 0이고 해당 날짜가 전년도의 마지막 주에

- 해당하면 전년도와 전년도의 마지막 주에 해당하는 순서를 가져온다.

mysql> select yearweek('2006-10-5',0), yearweek('2006-10-5',1);
+-------------------------+-------------------------+
| yearweek('2006-10-5',0) | yearweek('2006-10-5',1) |
+-------------------------+-------------------------+
| 200640 | 200640 |
+-------------------------+-------------------------+
1 row in set (0.00 sec)

mysql>

- HOUR(time)

- 0 에서 23 까지 중 해당 시간을 가져온다.

mysql> select hour('17:09:40');
+------------------+
| hour('17:09:40') |
+------------------+
| 17 |
+------------------+
1 row in set (0.00 sec)

mysql>

- MINUTE(time)

- 0 에서 59 까지의 숫자 중 해당 분을 가져온다.

mysql> select minute('17:09:40');
+--------------------+
| minute('17:09:40') |
+--------------------+
| 9 |
+--------------------+
1 row in set (0.00 sec)

mysql>

- SECOND(time)

- 0 에서 59 까지의 숫자 중 해당 초를 가져온다.

mysql> select second('17:09:40');
+--------------------+
| second('17:09:40') |
+--------------------+
| 40 |
+--------------------+
1 row in set (0.00 sec)

mysql>


- PERIOD_ADD(P,N)

- P 기간에 N 달 만큼 더한 결과를 YYYYMM 형태로 가져온다.

- 이때 P 는 YYMM 혹은 YYYYMM 형태일 뿐 date 값은 아님에 유의하시 바란다.

mysql> select period_add(9810,2);
+--------------------+
| period_add(9810,2) |
+--------------------+
| 199812 |
+--------------------+
1 row in set (0.00 sec)

mysql>

- PERIOD_DIFF(P1,P2)

- YYMM 혹은 YYYYMM 형태의 P1 과 P2 가 몇달 사이인지 가져온다.

- 이때 P1, P2 는 date 값이 아니다.

mysql> select period_diff(9802,199703);
+--------------------------+
| period_diff(9802,199703) |
+--------------------------+
| 11 |
+--------------------------+
1 row in set (0.00 sec)

mysql>

- DATE_ADD(date,INTERVAL expr type) 혹은 ADDDATE(date,INTERVAL expr type)

- date 로부터 expr 만큼 type 단위로 더한 결과를 가져온다.

- DATE_SUB(date,INTERVAL expr type) 혹은 SUBDATE(data,INTERVAL expr type)

- date 로부터 expr 만큼 type 단위로 뺀 견롸를 가져온다.

- expr 과 type 이 어떻게 관계를 가지는지 나타낸 표는 다음과 같다.

+----------------------------------------+

| type 값 | expr 형태 |

+----------------------------------------+

| SECOND | 초 |

| MINUTE | 분 |

| HOUR | 시 |

| DAY | 날 |

| MONTH | 달 |

| YEAR | 년 |

| MINUTE_SECOND | 분:초 |

| HOUR_MINUTE | 시:분 |

| DAY_HOUR | 날 시 |

| YEAR_MONTH | 년-달 |

| HOUR_SECOND | 시:분:초 |

| DAY_MINUTE | 날 시:분 |

| DAY_SECOND | 날 시:분:초 |

+----------------------+-----------------+

mysql> select date_add("1997-12-31 23:59:59", interval 1 day);
+-------------------------------------------------+
| date_add("1997-12-31 23:59:59", interval 1 day) |
+-------------------------------------------------+
| 1998-01-01 23:59:59 |
+-------------------------------------------------+
1 row in set (0.00 sec)

mysql>

- 1997-12-31 23:59:59 에 하루를 더해서 1998-01-01 23:59:59 값이 리턴된다.

mysql> select date_add("1997-12-31 23:59:59", interval "1:1" minute_second);
+---------------------------------------------------------------+
| date_add("1997-12-31 23:59:59", interval "1:1" minute_second) |
+---------------------------------------------------------------+
| 1998-01-01 00:01:00 |
+---------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

- 1997-12-31 23:59:59 에 1분 1초가 더해져서 1998-01-01 00:01:00 값이 리턴된다.

mysql> select date_add("1998-01-01 00:00:00", interval "-1 10" day_hour);
+------------------------------------------------------------+
| date_add("1998-01-01 00:00:00", interval "-1 10" day_hour) |
+------------------------------------------------------------+
| 1997-12-30 14:00:00 |
+------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

- 1998-01-01 00:00:00 에서 하루 10시간 이전 즉 34시간 이전 의 값인

- 1997-12-30 14:00:00 이 리턴된다.

mysql> select date_sub("1998-01-02", interval 31 day);
+-----------------------------------------+
| date_sub("1998-01-02", interval 31 day) |
+-----------------------------------------+
| 1997-12-02 |
+-----------------------------------------+
1 row in set (0.00 sec)

mysql>

- 1998-01-02 에서 31일이 빼어진 1997-12-02 가 리턴된다.

mysql> select date_add("1998-01-30", interval 1 month);
+------------------------------------------+
| date_add("1998-01-30", interval 1 month) |
+------------------------------------------+
| 1998-02-28 |
+------------------------------------------+
1 row in set (0.00 sec)

mysql>

- 위와 같이 30 일 간격의 날짜가 2 달을 넘어가게 될 경우 MONTH 간격은 30일 간격이

- 아니라 다음 달의 마지막 날까지로 계산한다.

- EXTRACT(type FROM date)

- date 로부터 type 형태로 결과를 추출하여 가져온다.

- 이때 type 은 DATE_ADD(), DATE_SUB() 에서 사용하는 type 과 같은 형태이다.

mysql> select extract(day_hour from "1998-12-31 23:33:33");
+----------------------------------------------+
| extract(day_hour from "1998-12-31 23:33:33") |
+----------------------------------------------+
| 3123 |
+----------------------------------------------+
1 row in set (0.00 sec)

mysql>

- TO_DAYS(date)

- 0 년부터 계산한 날짜수를 가져온다.

- 참고로 TO_DAYS()는 그레고리력(1582)을 따르지 않는다.

mysql> select to_days('2006-10-05');
+-----------------------+
| to_days('2006-10-05') |
+-----------------------+
| 732954 |
+-----------------------+
1 row in set (0.00 sec)

mysql>

- FROM_DAYS(N)

- 0 년부터 계산된 날짜수로부터 날짜를 가져온다.

- 참고로 FROM_DAYS()는 그레고리력(1582)을 따르지 않는다.

mysql> select from_days('732954');
+---------------------+
| from_days('732954') |
+---------------------+
| 2006-10-05 |
+---------------------+
1 row in set (0.00 sec)

mysql>

- DATE_FORMAT(date,format)

- 날짜를 원하는 문자열 형태로 바꿀 때 매우 유용하게 사용되는 함수이다.

- format 에는 특정한 문자들을 열거하여 원하는 문자열을 만든다.

- format 에 열거할 수 있는 문자와 그 설명은 다음 표와 같다.

+------+-------------------------------------------------------------------------------+

|열거자| 설명 |

+------+-------------------------------------------------------------------------------+

| %M | 달 이름 (January, December) |

| %W | 요일 이름 (Sunday, Saturday) |

| %D | 1st, 2nd 와 같은 영문법에 의한 해당 달의 날짜 |

| %Y | YYYY 형태의 연도 |

| %y | YY 형태의 연도 |

| %X | 해당 날짜에 대해 일요일로 시작하는 주를 기준으로 YYYY 형태의 연도를 가져온다. |

| | %v 와 함깨 쓰인다. |

| %x | 해당 날짜에 대해 월요일로 시작되는 주를 기준으로 YYYY 형태의 연도를 가져온다. |

| | %v 와 함깨 쓰인다. |

| %a | Sun, Sat 와 같은 요일의 약어 |

| %d | 00 에서 31 까지의 해당 달의 날짜 |

| %e | 0 에서 31 까지의 해당 달의 날짜 |

| %m | 01 에서 12 까지의 해당 년의 달 |

| %c | 1 에서 12 까지의 해당 년의 달 |

| %b | Jan, Dec 와 같은 달의 약어 |

| %j | 001 에서 366 까지의 해당 년의 날짜 |

| %H | 00 에서 23 까지의 시 |

| %k | 0 에서 23 까지의 시 |

| %h | 01 에서 12 까지의 시 |

| %l | 01 에서 12 까지의 시 |

| %L | 1 에서 12 까지의 시 |

| %i | 00 에서 59 까지의 분 |

| %r | 12 시간 기준으로 시간을 hh:mm:ss [AP]M 형태로 가져온다. |

| %T | 24 시간 기준으로 시간을 hh:mm:ss 형태로 가져온다. |

| %S | 00 에서 59 까지의 초 |

| %s | 00 에서 59 까지의 초 ( %S 와 같다. ) |

| %p | AM 혹은 PM |

| %w | 0 에서 6 까지 요일을 가져온다. ( 0=Sunday..6=Saturday ) |

| %U | 00 에서 53 까지 해당 년의 몇번째 주인가를 가져온다. 일요일이 시작인 주를 기준 |

| %u | 00 에서 53 까지 해당 년의 몇번째 주인가를 가져온다. 월요일이 시작인 주를 기준 |

| %V | 01 에서 53 까지 해당 년의 몇번째 주인가를 가져온다. 일요일이 시작인 주를 기준 |

| | ' %X ' 와 함깨 쓰인다. |

| %v | 01 에서 53 까지 해당 년의 몇번째 주인가를 가져온다. 월요일이 시작인 주를 기준 |

| | ' %x ' 와 함깨 쓰인다. |

| %% | ' % ' 문자를 그대로 가져온다. |

+-----+--------------------------------------------------------------------------------+

mysql> select date_format('1997-10-04 22:23:00', '%W %M %Y');
+------------------------------------------------+
| date_format('1997-10-04 22:23:00', '%W %M %Y') |
+------------------------------------------------+
| Saturday October 1997 |
+------------------------------------------------+
1 row in set (0.09 sec)

mysql>

- %W 는 요일 이름을 리턴, %M 은 달 이름을 리턴, %Y는 YYYY 형태의 연도를 리턴

mysql> select date_format('1997-10-04 22:23:00', '%H:%i:%s');
+------------------------------------------------+
| date_format('1997-10-04 22:23:00', '%H:%i:%s') |
+------------------------------------------------+
| 22:23:00 |
+------------------------------------------------+
1 row in set (0.00 sec)

mysql>


- %H는 00에서 23까지의 시를 리턴,%i 는 00에서 59까지의 분을 리턴,%s 00에서 59까지의 초 리턴

mysql> select date_format('1999-01-01', '%X %V');
+------------------------------------+
| date_format('1999-01-01', '%X %V') |
+------------------------------------+
| 1998 52 |
+------------------------------------+
1 row in set (0.00 sec)

mysql>

- %X 는 해당 날짜에 대해 일요일로 시작하는 주를 기준으로 YYYY 형태의 연도를 리턴

- %V 는 01 에서 53 까지의 해당 년의 몇번째 주인가를 리턴. 일요일이 시작인 주를 기준

- TIME_FORMAT(time, format)

- DATE_FORMAT() 과 같은 방법으로 사용되는 함수이다. 단지 time 에 시간 값이 들어가고

- format 에는 DATE_FORMAT() 에서 사용하는 열거자 중 시간이나 분, 초에 해당하는

- 열거자만 들어가야 한다는 차이다 있다.

- CURDATE() 혹은 CURRENT_DATE()

- 함수가 문자열처럼 사용되느냐 숫자처럼 사용되느냐에 따라 현재 날짜를 'YYYY-HH-DD'

- 혹은 'YYYYMMDD' 형태로 가져온다.

mysql> select curdate(), curdate()+0, curdate()+1;
+------------+-------------+-------------+
| curdate() | curdate()+0 | curdate()+1 |
+------------+-------------+-------------+
| 2006-10-06 | 20061006 | 20061007 |
+------------+-------------+-------------+
1 row in set (0.00 sec)

mysql>

- CURTIME() 혹은 CURRENT_TIME

- 함수가 문자열처럼 사용되느냐 숫자처럼 사용되느냐에 따라 현재 시간은 'HH:MM:SS'

- 혹은 'HHMMSS' 형태로 가져온다.

mysql> select curtime(), curtime()+0, curtime()+1;
+-----------+-------------+-------------+
| curtime() | curtime()+0 | curtime()+1 |
+-----------+-------------+-------------+
| 01:08:59 | 10859 | 10860 |
+-----------+-------------+-------------+
1 row in set (0.00 sec)

mysql>

- UNIX_TIMESTAMP 혹은 UNIX_TIMESTAMP(date)

- 인자가 없는 경우에는 현재의 Unix 시간 ('1970-01-01 00:00:00' 을 기준으로 초단위) 을

- 가져온다. date 인자가 있는 경우에는 date 의 Unix 시간 ('1970-01-01 00:00:00' 을

- 기준으로 초단위) 을 가져온다.

mysql> select unix_timestamp(), unix_timestamp('2002-05-04 22:23:00');
+------------------+---------------------------------------+
| unix_timestamp() | unix_timestamp('2002-05-04 22:23:00') |
+------------------+---------------------------------------+
| 1160066173 | 1020518580 |
+------------------+---------------------------------------+
1 row in set (0.00 sec)

mysql>

- FROM_UNIXTIME(unix_timestamp)

- 문자열처럼 사용되느냐 숫자처럼 사용되느냐에 따라 유닉스 시간을 'YYYY-MM-DD HH:MM:SS'

- 혹은 'YYYYMMDDHHMMSS' 형태로 가져온다.

- FROM_UNIXTIME(unix_timestamp,format)

- 유닉스 시간을 원하는 형태로 변환하여 가져온다. format 에 들어갈 열거자들은

- DATE_FORMAT() 함수에서 사용하는 열거자들을 사용할 수 있다.

mysql> select from_unixtime(unix_timestamp(), '%Y %D %M %h:%i:%s %x');
+-----------------------------------------------------------+
| from_unixtime(unix_timestamp(), '%Y %D %M %h:%i:%s %x') |
+-----------------------------------------------------------+
| 2006 6th October 01:40:17 2006 |
+-----------------------------------------------------------+
1 row in set (0.38 sec)

mysql>


- SEC_TO_TIME(seconds)

- 초를 시,분,초 형태로 변환한다. 함수가 문자열처럼 사용되느냐 숫자처럼 사용되느냐에 따라

- 'HH:MM:SS' 혹은 'HHMMSS' 형태로 가져온다.

mysql> select sec_to_time(2378);
+-------------------+
| sec_to_time(2378) |
+-------------------+
| 00:39:38 |
+-------------------+
1 row in set (0.36 sec)

mysql>

- TIME_TO_SEC(time)

- time 을 초로 변환한다.

mysql> select time_to_sec('22:23:00');
+-------------------------+
| time_to_sec('22:23:00') |
+-------------------------+
| 80580 |
+-------------------------+
1 row in set (0.00 sec)

mysql>


Compressing and DeCompressing a File in C#


By Cosmos Mysore
Printer Friendly Version
View My Articles
10 Points

Methods to compress file and decompress file using System.IO.Compression



Method to compress a file.

public void CompressFile ( string sourceFile, string destinationFile )

{

// Check File exists in the source path

if ( File.Exists ( sourceFile ) == false )

throw new FileNotFoundException ( );

// Create the streams and byte arrays

byte[] buffer = null;

FileStream sourceStream = null;

FileStream destinationStream = null;

GZipStream compressedStream = null;

try

{

// Read the bytes from the source file into a byte array

sourceStream = new FileStream ( sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read );

// Read the source stream values into the buffer

buffer = new byte[sourceStream.Length];

int checkCounter = sourceStream.Read ( buffer, 0, buffer.Length );

if ( checkCounter != buffer.Length )

{

throw new ApplicationException ( );

}

// Open the FileStream to write

destinationStream = new FileStream ( destinationFile, FileMode.OpenOrCreate, FileAccess.Write );

// Create a compression stream pointing to the destiantion stream

compressedStream = new GZipStream ( destinationStream, CompressionMode.Compress, true );

// Now write the compressed data to the destination file

compressedStream.Write ( buffer, 0, buffer.Length );

}

catch ( ApplicationException ex )

{

MessageBox.Show ( ex.Message, "Error occured during compression", MessageBoxButtons.OK, MessageBoxIcon.Error );

}

finally

{

// Close all streams

if ( sourceStream != null )

sourceStream.Close ( );

if ( compressedStream != null )

compressedStream.Close ( );

if ( destinationStream != null )

destinationStream.Close ( );

}

}


Method to DeCompress a file.


public void DecompressFile ( string sourceFile, string destinationFile )

{

// Check File exists in the source path

if ( File.Exists ( sourceFile ) == false )

throw new FileNotFoundException ( );

// Create the streams and byte arrays needed

FileStream sourceStream = null;

FileStream destinationStream = null;

GZipStream decompressedStream = null;

byte[] quartetBuffer = null;

try

{

// Read in the compressed source stream

sourceStream = new FileStream ( sourceFile, FileMode.Open );

// Create a compression stream pointing to the destiantion stream

decompressedStream = new GZipStream ( sourceStream, CompressionMode.Decompress, true );

// Read the footer to determine the length of the destiantion file

quartetBuffer = new byte[4];

int position = (int)sourceStream.Length - 4;

sourceStream.Position = position;

sourceStream.Read ( quartetBuffer, 0, 4 );

sourceStream.Position = 0;

int checkLength = BitConverter.ToInt32 ( quartetBuffer, 0 );

byte[] buffer = new byte[checkLength + 100];

int offset = 0;

int total = 0;

// Read the compressed data into the buffer

while ( true )

{

int bytesRead = decompressedStream.Read ( buffer, offset, 100 );

if ( bytesRead == 0 )

break;

offset += bytesRead;

total += bytesRead;

}

// Now write to the destination file

destinationStream = new FileStream ( destinationFile, FileMode.Create );

destinationStream.Write ( buffer, 0, total );

// Flush to clean out the buffer

destinationStream.Flush ( );

}

catch ( ApplicationException ex )

{

MessageBox.Show ( ex.Message, "An Error occured during compression", MessageBoxButtons.OK, MessageBoxIcon.Error );

}

finally

{

// Close all streams

if ( sourceStream != null )

sourceStream.Close ( );

if ( decompressedStream != null )

decompressedStream.Close ( );

if ( destinationStream != null )

destinationStream.Close ( );

}

}

'기본 카테고리' 카테고리의 다른 글

m480  (0) 2009.02.19
MySQL 날짜 시간 함수  (0) 2009.02.18
Writing an ActiveX control in C#  (0) 2009.02.17
ClickOnce Deployment Limitations  (0) 2009.02.09
우분투 넷북 리믹스(Netbook remix)  (0) 2009.02.02

Writing an ActiveX control in C#

Published: 20 Apr 2007
By: Imran Nathani

An ActiveX control is an object that supports a customizable programmatic interface. Using the methods, events and properties exposed by the control, web developers can automate their web pages to give the functionality which is equivalent to that of a desktop application.

Introduction

As web application developers, we want to give our users a highly functional application. We want to provide our users with functionality like printing streams, local socket programming ,local threading, cross domain scripting etc., but as we know that due to the disconnected architecture of the Internet and security restrictions of any standard browser, this task becomes difficult. That’s when the ActiveX comes to the rescue. This is mostly for web applications where the users would not be apprehensive about doing a one time installation of the component. Also, in an intranet application these components can be a big boost to the functionality of the application.

Writing ActiveX Class in C#

We will first write an interface called ASignatures which holds the signatures of the methods and properties. These methods and properties can then be accessed via JavaScript at the browser level. By default all members of an interface are abstract and public. The main ActiveX class AClass will inherit from this interface. Above the main ActiveX class we will mention the ClassInterfaceType as AutoDual. This will indicate the type of the interface generated for the main class which will automatically be generated and exposed to the COM. Normally AutoDual is not recommended because it has some versioning limitations. We will use the ClassIntrefaceType as AutoDual because the purpose of this code is instructional. In the main class we will write two methods FName(), and SName() and one property Age. In our example we will return the basic datatypes but this can be implemented for complex datatypes too.

using System;using System.Runtime.InteropServices;namespace ANamespace {  public interface ASignatures  {    string FName();    string SName();    int Age { get;}    }  [ClassInterface(ClassInterfaceType.AutoDual)]  public class AClass :ASignatures  {    public string FName()    {      return "Imran";    }    public string SName()    {      return "Nathani";    }    public int Age    {      get { return 24; }    }  }}

Compiling the ActiveX control

For those who do not know how to compile out of Visual Studio IDE, you need to search for the c# compilercsc.exe in the folder:

\WINDOWS\Microsoft.NET\Framework\v2.0.xxxxx

Place your AClass.cs file in the folder where the csc.exe exists. Then by command (DOS) interface go to that particular folder and execute the following command:

csc /t:library AClass.cs

Registering the Assembly with the client

You can register the assembly in multiple ways of implementation and it mostly depends on the target users. For example, creating a setup file for download or having a self extractor file which could prompt in the browser, depends totally on the functionality requirement. However for our example we would register the assembly by using the command prompt which is the easiest and could be done by a batch file too. Therefore, in same folder as above immediately after the compilation step we execute the following command:

regasm AClass.dll /tlb /codebase

Also we must note that the .NET Framework needs to be installed on the client for registration and working.

Using the ActiveX control

We can then access our newly created ActiveX control via JavaScript. We will simply display the data returned by the methods and property in alert boxes. The below code demonstrates how we can access the properties in the ActiveX control.

<html><head>  <script language="javascript">    <!-- Load the ActiveX object  -->    var x = new ActiveXObject("ANamespace.AClass");    <!-- Access the Method -->    alert(x.FName());    alert(x.SName());    <!-- Access the Property -->    alert(x.Age);  </script></head><body></body></html>

This will work like a charm in Internet Explorer but may need an API plugin for other browsers like FireFox or Safari.

Summary

In this article you have seen how we can increase the functionality of our web application by implementation of ActiveX controls in C#. The practical applications of ActiveX are limitless especially for graphics and multimedia.

About Imran Nathani

Sorry, no bio is available

View complete profile

+ Recent posts