2016. 11. 22. 21:00 Scripts/Python

python 입문기

여러 글에서 밝혀왔듯 나는 rubyist다. ruby를 사랑하는 이유는 내가 접했던 언어 중 가장 즐겁게 코딩이 가능했기 때문이다. rails는... 음 이제와 밝히자면, 사실 좀 어려웠다.

ruby가 어려웠다기보다는, 웹에 대한 이해도가 전무한 개발자가 쉽게 기능 개발을 해볼 순 있지만, production 과정까지 가는게 쉽지만은 않았다랄까?


ruby는 해외와는 달리 국내에서는 비주류라는 점이 고민의 포인트가 되긴했지만, 해외에서의 높은 인지도로 인한 풍부한 자료는 그 거부감을 상쇄 시켜줬다.


성능상의 이슈가 있다지만 어지간한 규모의 트래픽으론 성능 이슈를 제기할 정도로 열악한 것도 아니다.


오히려 가장 아쉬웠던 점은 rails가 갖는 장점인 학습 속도에 비해, 단점인 프로덕션 과정에서의 학습 비용이 큰 편이었던 점이라고 할 수 있다.


특히 DB관련한 연동은 추상화 레이어로 인한 개발 과정 이득은 있지만, 인덱스 개념이나 데이터 모델링 개념이 부족한 경우에 프로덕션 트러블의 요인이 되기 쉽상이다. 물론 이는 다른 언어들의 프레임워크들도 가진 문제지만, ruby on rails는 쉬운 학습 비용이 장점인 프레임워크이기 때문에, 이 부분이 조금 더 감점 요인이라고 생각한다.



물론 나는 위 모든 점을 감안해도 rails가 좋다. 여전히.

ruby도 물론이고.


몇번이나 이런 질문을 받은 적이 있다. 왜 rails를 썼냐고.

국내 기준으로 C++이 여전히 주류이고, 웹 기반 서버로 많이 넘어가던 시기에도 php, asp.net, node.js, jsp 등이 주류이던 시기에, 심지어 python도 아닌 ruby였냐고.


그 질문에 나는 항상 같은 대답을 했다.


"내가 그 당시 학습하려 시도한 모든 언어들 중에 ruby가 가장 즐거웠노라고."


업무는 내 삶에서 큰 부분을 차지한다.

그 과정이 즐겁지 않다면, 내 삶이 즐겁지 않을 수 도 있다.

그래서 나는 내가 업무를 즐겁게 하기 위한 선택을, 가능하다면 많이 하려고 하는데, 그 과정에서 ruby는 꽤나 높은 점수를 줄 수 있었다.


그렇다면 python도 즐거워서 골랐나?

그렇진 않았다.


내가 느낀 국내 인지도는


Java > C++ > C# > Python > Ruby > Golang = scala 였다.

사실 나는 ruby 다음 언어로 Golang이나 scala를 해보고 싶었음을 지난 글에서 밝힌 바 있다.


하지만 현재 시점에서 “웹 서버”를 구현해야 할 언어를 골라야 한다는 관점에서, Golang은 시기상조인 면이 많고, 특히 웹서버로 구동하기엔 여타 프레임워크보다 아쉬움을 갖고 있다.

scala로 Play! 프레임워크를 사용해보려 고민도 했으나, 그러기에는 내가 너무 java에 대한 이해도가 부족했다.


게다가 나는 C++ > C# > Java의 선호도를 갖고 있고.



그리하여, ruby와 비슷한 급(?)의 언어이면서, 국내에서의 인지도가 ruby보다 높은 python을 해보기로 했다.


rails를 다시 선택하는 방법도 있었지만, 웹 프레임워크로써 프로덕션 레벨에 올려본 것이 rails 하나이기 때문에 다른 웹 프레임워크의 장단점과 다른 언어 학습의 기회를 같이 맛보기 위한 선택을 하게 됐다.



그렇게 python을 입문하고 나니, 몇 가지 감상이 들어 3달여간 사용해본 경험을 정리해보고자 한다.



indent 강제.

사실상 내가 python보다 ruby를 애호하게 된 이유다.


indent 에도 취향이 있는 것이고, 나는 프로그래밍이 재밌어야, 일이 재밌어야 한다고 주장하는 입장에서 자유도를 억제하는 느낌드는 파이썬의 indent강제는 거부감이 들었다랄까?


막상 사용해보니 코드 읽기에 큰 강점이 있더라.


실제 동작을 유추하기 쉽다보니, 여러모로 메리트가 있었다.


다만 다른 언어들과 조금 다른 것들이 많은데, 예를들어


조건문이나 함수 정의에 :이 마지막에 붙는 점이다.


# ruby
def test()
	statement
# python
def test(abc):
	statement
다음과 같아 진다.

조건문의 경우에도 마찬가지로,

# ruby
if aaa
	statement
end
# python
if aaa:
	statement
같은 형태가 된다.


다들 아시다시피, 들여쓰기가 depth에 따라 코드가 어떤 단락에 포함되는지를 결정짓는다.
# ruby
# 들여쓰기 1
if aaa
	statement
	statement2
end

# 들여쓰기 2
if aaa
	statement
statement2
end
# python
# 들여쓰기 1
if aaa:
	statement
	statement2

# 들여쓰기 2
if aaa:
	statement
statement2
루비는 두 결과가 같다.
하지만, 파이썬은 다르다. 들여쓰기 2에서, aaa 조건이 성립하지 않아도 statement2는 실행된다.


이런 제약이 거추장 스럽게 느껴진게 사실이다.
C++에 비해 상대적 자유도가 낮은 java를 선호하지 않았던 이유도 같은 이유였기 때문인데, 굳이 스크립트 언어에 제약이 있는 언어를 고르지 않겠단 생각이었다.

헌데 막상 파이썬을 사용해보니, 협업에 큰 장점이 있었다.
RSA 알고리즘을 한 줄에 짤 수 있네 마네 말도 많은 perl을 겪은 나로썬, 또 지나친 자유도로 소통 비용을 크게 요구하는 C++을 오래 사용해온 입장에서 크게 와닿으며, 인정하게 된 것은, indent강제가 코드 읽기 비용을 크게 낮춰준다는 것을 확실히 느낄 수 있었다.

이는 디버깅이나 오류 비용이 크게 낮아진다는 얘기기도 하다.

내가 크게 걱정했던 표현력이 막상 크게 제한되지도 않았다.
팀작업에서 큰 이득이 있었고, 오픈소스 코드 분석에서도 큰 장점이 됐다.

아니, 다른 언어들도 이래야 하는거 아닌가 싶을 정도로 마음에 들었다는게 맞겠다.

대다수의 팀에서 일하는 프로그래머들은 팀 코드만 보지 않는다.

오픈소스 진영에서의 개발은 특히나, 다른 사람의 코드를 봐야 할 일이 아주 많다.

그런 측면에서 아주 큰 강점이 있다는 생각이 들었다.



거기에 부가적으로, python도 말하면서 코딩하는 기분이 들었다.
if user is None:
	blah blah

이 얼마나 직관적인가?


django로 개발하면서 머릿속의 내용을 코드로 옮기는데에 멈칫하는 과정없이 술술 진행될 수 있었던 것은, python의 문법이 유연하진 못하지만, 대화하는 느낌이 드는 언어였기 때문이다.


이 점이 나에게 python에 대한 인상을 좋게 만들어주는 요인이 되었다.



나에게있어 python은 어려운 언어는 아니었다.

사실 쉽게 익숙해진 언어라 볼 수 있다고 본다.



ruby를 먼저 접했어서 인지, 아니면 python 자체가 쉬워서인지는 잘 모르겠지만, 여러모로 ruby와는 또 다른 즐거움을 가져다준 언어였다고 생각한다.



이어지는 django 사용기에 조금 더 디테일한 python 사용기를 담아볼 예정이다.

'Scripts > Python' 카테고리의 다른 글

python 입문기  (0) 2016.11.22
Posted by 엘키 엘키

댓글을 달아 주세요

2014. 11. 4. 23:19 Scripts/Ruby

Welcome to ruby!


루비를 시작하시는 모든분들께 짧게 읽고 넘어가실 수 있는 슬라이드를 작성해보았습니다.
동적 타입 기반의 스크립트 언어를 아직 해보지 않으셨다면, 파이썬이나 루비! 기왕이면 루비를 추천해드립니다.
짧게 5분정도 소요되니 읽고 가셔요~


'Scripts > Ruby' 카테고리의 다른 글

Welcome to ruby!  (0) 2014.11.04
Ruby invalid byte sequence in UTF-8 (Argument Error)  (0) 2014.10.30
루비에서 쉘 명령을 내리는 방법  (0) 2014.06.03
루비 주석  (0) 2014.02.07
루비 변수 관련 정리  (0) 2013.05.14
Ruby가 모듈을 찾는 장소.  (0) 2013.05.09
Posted by 엘키 엘키
 TAG ruby, 루비

댓글을 달아 주세요

text file을 line별 parsing을 하고 split 하려던 중, 오류 발생.
-> ruby invalid byte sequence in utf 8
-> ruby도 encoding 문제에서 자유롭지 못함.
-> 사실 이건 모든 프로그래밍 언어의 문제...정확히는 윈도우와의 호환에서 생기는 문제.
-> 해당 문자열에 force_encoding("iso-8859-1").encoding("UTF-8")을 하니 처리 되기 시작.
-> 헌데, 읽혀진 문자열에 유효하지 않은 공백이 포함됨.

text 파일이 ANSI, utf-8은 정상적으로 읽힘. 헌데, unicode option의 text file만 안읽힘. (notepad encoding option중 utf-8, ANSI는 정상적이고, unicode에서만 문제가 생김)
-> 각종 encoding option 으로 해결 안됨.
-> line 별 encoding 을 시도.
-> 첫번째 라인만 encoding 됨. 두번째 라인부터 꼬임.
-> line별 encoding을 확인해보았더니, 두번째 라인부터는 CP949 (ascii code page 949)로 인식되는 것을 확인.
-> C++에서 binary로 읽어 메모리값 확인해보니 처음 2byte가 254,255로 들어가 있었음. 이 값이 인코딩 방식에 대한 기록 값이었던 것.
-> 파일 전체를 열고 버퍼 전체를 인코딩 해보았더니 정상적으로 읽힘.
-> 해결!


정리하자면,
IO.foreach('file.rb') do | line |
    line.encode!("UTF-8", "UTF-16le", :invalid => :replace, :undefined => :replace, replace: "")
end



위와같이 변환시에는 첫 라인만 제대로 변환되고 두번째 라인부터는 값이 망가지더군요.


그래서, 

lines = Array.new
fSize = aFile.stat.size
if aFile
	content = aFile.sysread(fSize)
	content.encode!("UTF-8", "UTF-16le", :invalid => :replace, :undefined => :replace, replace: "")
	lines = content.split(/(\n)/)
else
	puts 'Unable open file'
end




위와같이 파일에서 읽은 내용 전체를 한번에 변환시 잘 처리 되었습니다.


stackoverflow의 관련 글

http://stackoverflow.com/questions/14035307/ruby-invalid-byte-sequence-in-utf-8-argumenterror

http://stackoverflow.com/questions/11065962/ruby-split-invalid-byte-sequence-in-utf-8-argumenterror

http://stackoverflow.com/questions/24036821/ruby-2-0-0-stringmatch-argumenterror-invalid-byte-sequence-in-utf-8

'Scripts > Ruby' 카테고리의 다른 글

Welcome to ruby!  (0) 2014.11.04
Ruby invalid byte sequence in UTF-8 (Argument Error)  (0) 2014.10.30
루비에서 쉘 명령을 내리는 방법  (0) 2014.06.03
루비 주석  (0) 2014.02.07
루비 변수 관련 정리  (0) 2013.05.14
Ruby가 모듈을 찾는 장소.  (0) 2013.05.09
Posted by 엘키 엘키

댓글을 달아 주세요

루비로 쉘 명령 내리는 방법 6가지
http://eriteia.blogspot.kr/2008/01/6.html


원문

http://blog.bigbinary.com/2012/10/18/backtick-system-exec-in-ruby.html


루비로 쉘 명령을 내리는 6가지 방법에 대해 나와있습니다.


가장 선호되는 방식은 open4지만...

현재 win32로는 open3까지만 지원하니 참고하세요.


win32에서 현재로써는 stdio를 사용하기 위해선 open3를 쓰시는 것이 좋습니다.


간단하게 실행 성공 여부까지만 필요하다면, system 함수를 통하시는 것이 가장 좋고, 이 경우 주의사항은 exit code가 TrueClass로 반환된다는 점 입니다.


TrueClass가 to_i를 지원하지 않는 만큼 확장해주시거나 랩핑해주셔야하며, 또 다른 단점은 정확한 exit code를 알 수 없다는 점 참고하세요.

'Scripts > Ruby' 카테고리의 다른 글

Welcome to ruby!  (0) 2014.11.04
Ruby invalid byte sequence in UTF-8 (Argument Error)  (0) 2014.10.30
루비에서 쉘 명령을 내리는 방법  (0) 2014.06.03
루비 주석  (0) 2014.02.07
루비 변수 관련 정리  (0) 2013.05.14
Ruby가 모듈을 찾는 장소.  (0) 2013.05.09
Posted by 엘키 엘키

댓글을 달아 주세요

2014. 2. 7. 17:34 Scripts/Ruby

루비 주석

.rb

기본

# blah blah


블럭 (여러 줄)
=begin
    blah blah        
=end


 *.html.erb

html 형식이므로,<!--  -->를 사용해야 합니다

'Scripts > Ruby' 카테고리의 다른 글

Ruby invalid byte sequence in UTF-8 (Argument Error)  (0) 2014.10.30
루비에서 쉘 명령을 내리는 방법  (0) 2014.06.03
루비 주석  (0) 2014.02.07
루비 변수 관련 정리  (0) 2013.05.14
Ruby가 모듈을 찾는 장소.  (0) 2013.05.09
루비 작업을 몇일 해본 감흥  (0) 2013.03.01
Posted by 엘키 엘키

댓글을 달아 주세요

정규 표현식(Regular Expression) 이란? 

문자열에서 특정한 캐릭터 조합(character combination)을 찾아내기위한 패턴(pattern)입니다.
특정 문자나 문자열로 문자열을 다루는 것에 문자뿐 만이 아니고 특수 문자로 다룰 수 있고 이들을 조합하여 다룰 수 있는 조건식(pattern)을 제공하여 더 세밀한 방법으로 문자들을 검색할 수 있게 합니다.

정규 표현식(Regular Expression) 생성 방법
1. object initializers를 사용한 방법
정규표현 =/패턴설정/[i/g/gi]var re = /ab+c/i
2. RegExp 객체의 constructor function를 사용한 방법
new RegExp("패턴 설정"[, "i", | ,"g", | "gi"])var re = new RegExp("ab+c", "i")
정규 표현식(Regular Expression) 플래그 구성 요소(생략 가능)
g완전일치(발생할 모든 pattern에 대한 전역 검색)
i대/소문자 무시
gi대/소문자 무시하고 완전 일치


정규 표현식(Regular Expression) 과 함께 사용하는 함수들
MethodType설명
exec()RegExp문장에서 매치를 위해 검색을 수행하는 정규 표현식 메소드
배열을 리턴
지정된 패턴과 같은 패턴을 찾는다.
test()RegExp문장에서 매치를 위해 테스트하는 정규표현식 메소드
True 또는 False 리턴
같은 패턴이 있는지 테스트 한다.
match()String문장에서 매치를 위해 검색을 수행하는 string 메소드
배열 또는 null 문자 리턴
지정된 패턴과 동일한 패턴을 찾는다.
search()String문장에서 매치를 위해 테스트하는 string 메소드
목차나 -1 리턴
첫번째로 일치하는 부분 문자열의 위치를 반환합니다
replace()String문장에서 매치를 위해 검색을 실행 문장을 대체하는 String 메소드
지정된 패턴과 바꾼다.
split()String문장에서 매치하는 부분을 배열에 할당하는 String 메소드
지정된 패턴부분에서 문자열을 나눈다.


정규 표현식에서 사용하는 특수문자
문자설명
다음에 나오는 특수 문자를 문자열로 인식
예 : \' 시퀀스는 ""를 찾고 '/'는 "/"를 찾습니다.
^입력 문자열의 시작 위치를 찾습니다.(라인의 처음과 패턴과 찾습니다.)
가령, ^A 라고 써주면 검색하고자 하는 문장의 시작문자가 A인지를 검사하는 것입니다.
$입력 문자열의 끝 위치를 찾습니다.(라인의 끝과 패턴과 찾습니다.)
가령, $A 라고 써주면 검색하고자 하는 문장의 마지막문자가 A인지를 검사하는 것입니다.
*0개 이상의 문자와 찾습니다.( 모든것이라는 의미 ==> {0,} 같은 의미 )
예 : "cg*"는 "c", "cginjs" 등입니다.
+1개 이상의 문자와 찾습니다.( {1,} 같은 의미임. )
예 : "cg+"는 "cg", "cginjs" 등이지만 "c"는 아닙니다.
?0 또는 1개의 문자 의미.( {0,1} 같은 의미임. )
예 : " C?j" 라면 C라는 문자와 j라는 문자사이에 문자가 0개 또는 1개 가 들어갈 수 있다는 말입니다.
      Cj, Cnj, Cgj등과 같은..
."n"을 제외한 모든 단일 문자를 찾습니다.
"n"을 포함한 모든 문자를 찾으려면 '[.n]' 패턴을 사용하십시오.
()한번 match를 수행해서 나온 결과를 기억함.
예 : /(cnj)/ 는 cnj라는 단어를 검색한 후, 그 단어를 배열등과 같은 저장장소에 남겨두어 나중에 다시 호출할 수 있도록 합니다.
|OR
{n}정확히 n개의 문자(n은 음이 아닌 정수)
예: a{2} 는 a 문자 두 개, 즉, aa를 의미합니다.
{n,}n정확히 n개 찾습니다.(n,음이 아닌 정수)
예 : "c{2}"는 "cnj"의 "c"는 찾지 않지만 "bcccccccccf"의 모든 c는 찾습니다.
{n,m}최소 n개, 최대 m개 찾습니다.(n은 음이 아닌 정수)
예 : "b{1,4}"은 "bcccccccccf"의 처음 네 개의 c를 찾습니다.
쉼표와 숫자 사이에는 공백을 넣을 수 없습니다.
[xyz]괄호 안의 문자 중 하나를 찾습니다.(문자들의 set를 의미)
가령, [a-z]라면 a부터 z까지의 모든 문자와 찾습니다.하는 것으로 []안의 -는 범위를 나타냅니다.
괄호 안의 문자 중 하나를 찾습니다.
예:, "[abc]"는 "cnj"의 "c"를 찾습니다.
[^xyz]제외 문자 집합입니다.(네가티브(-) 캐릭터 셋)
괄호 밖의 문자 중 하나를 찾습니다.
예 : "[^abc]"는 "acn"의 "n"를 찾습니다.
x|yx 또는 y를 찾습니다.
예 : "c|cginjs"는 "c" 또는 "cginjs"를 찾습니다.
[a-z]문자 범위입니다.(지정한 범위 안의 문자를 찾습니다)
예 : "[a-z]"는 "a"부터 "z" 사이의 모든 소문자를 찾습니다.
[^a-z]제외 문자 범위입니다(지정된 범위 밖의 문자를 찾습니다)
예 : "[^a-z]"는 "a"부터 "z" 사이에 없는 모든 문자를 찾습니다.
[b]백스페이스와 찾습니다.
b단어와 공백 사이의 위치를 찾습니다.(단어의 경계)
예 : "erb"는 "never"의 "er"는 찾지만 "verb"의 "er"는 찾지 않습니다.
B단어의 비경계를 찾습니다.
예 : "erB"는 "verb"의 "er"는 찾지만 "never"의 "er"는 찾지 않습니다.
cXX 가 나타내는 제어 문자를 찾습니다.(control 문자와 찾습니다)
예 : cM은 Control-M 즉, 캐리지 리턴 문자를 찾습니다.
      x 값은 A-Z 또는 a-z의 범위 안에 있어야 합니다.
      그렇지 않으면 c는 리터럴 "c" 문자로 간주됩니다.
d0부터 9까지의 아라비아 숫자와 찾습니다.. [0-9]과 같은 의미
D비숫자 문자를 찾습니다. [^0-9]와 같습니다.
f폼피드 문자(form-feed)를 찾습니다.(x0c와 cL과 같은 의미)
nlinefeed(줄 바꿈 문자)를 찾습니다.(x0a와 cJ과 같은 의미)
r캐리지 리턴 문자를 찾습니다(x0d와 cM과 같은 의미)
s공백, 탭, 폼피드 등의 공백을 찾습니다.( [ tnrfv]과 같은 의미)
Ss가 아닌 문자(공백이 아닌 문자)를 찾습니다. ( [^ tnrfv]과 같은 의미)
t탭 문자를 찾습니다. (x09와 cI와 같은 의미)
v수직 탭 문자를 찾습니다.(x0b와 cK와 같은 의미)
w밑줄을 포함한 모든 단어 문자를 찾습니다.( "[A-Za-z0-9_]"와 같은 의미)
W문자가 아닌 요소,
즉 % 등과 같은 특수 문자를 의미함( "[^A-Za-z0-9_]"와 같은 의미)
nn은 마지막 일치하는 문장
xnn을 찾습니다. 여기서 n은 16진수 이스케이프 값입니다.
16진수 이스케이프 값은 정확히 두 자리여야 합니다.
예 : 'x41'은 "A"를 찾고 'x041'은 'x04'와 "1"과 같습니다.
       정규식에서 ASCII 코드를 사용할 수 있습니다.
numnum을 찾습니다.(num은 양의 정수)
캡처한 문자열에 대한 역참조입니다.
예 : '(.)1'은 연속적으로 나오는 동일한 문자 두 개를 찾습니다.
nm8진수 이스케이프 값이나 역참조를 나타냅니다.
nm 앞에 최소한 nm개의 캡처된 부분식이 나왔다면 nm은 역참조입니다.
nm 앞에 최소한 n개의 캡처가 나왔다면 n은 역참조이고 뒤에는 리터럴 m이 옵니다.
이 두 경우가 아닐 때 n과 m이 0에서 7 사이의 8진수이면 nm은 8진수 이스케이프 값 nm을 찾습니다.
nmln이 0에서 3 사이의 8진수이고 m과 l이 0에서 7 사이의 8진수면 8진수 이스케이프 값 nml을 찾습니다.
unn은 4 자리의 16진수로 표현된 유니코드 문자입니다.
예 : u00A9는 저작권 기호(ⓒ)를 찾습니다.
ooctal
xhex
8(octal)진수, 10(hex)진수 값


정규 표현식에서 사용하는 property
속성설명
global완전 일치
ignoreCase대문자 소문자 무시
lastIndex다음 패턴조회를 시작하는 위치
source조회시킬 패턴
input검색 문자열의 설정, 변경($_로도 가능)
multiline줄바구기 코드를 무시할지 여부($_로도 가능)
참(무시하지 않는다), 거짓(무시한다.)로 설정
lastMatch패턴 조회한 최후의 문자($&로도 가능)
lastParen패턴 조회한 최후의 substring($+로도 가능)
leftContext패턴 조회한 값의 앞의 문자($¥Q로도 가능)
rightContext패턴 조회한 값의 다음 문자($'로도 가능)
$1~$9패턴 조회한 것의 일부를 저장한다.(9개까지




정규 표현식(Regular Expression) 사용예제 1

  1. <SCRIPT LANGUAGE="JavaScript">
  2. <!--
  3. function cnj_regexp() {
  4. // 'c' 가 있는 문자열이 있으면 TRUE (대/소문자 구분)
  5. var cnj_re = /c/
  6. var cnj_ment = "'c' 가 있는 문자열이 있으면 TRUE (대/소문자 구분)nn변수 : " + cnj_re;
  7. if (cnj_re.test("When Cgi Met Javascript = CginJs.Com") == true) {
  8. alert(cnj_ment + "nn문자열이 있군요(true)");
  9. } else {
  10. alert(cnj_ment + "nn문자열이 없군요(fail)");
  11. }
  12. }
  13. //-->
  14. </SCRIPT>
  15. <input type="button" name="cnj_text" value="확인" omClick="cnj_regexp()">


정규 표현식(Regular Expression) 사용예제 2

  1. <SCRIPT LANGUAGE="JavaScript">
  2. <!--
  3. function cnj_regexp() {
  4. // 'CGINJS' 가 있는 문자열이 있으면 TRUE (대/소문자 구분)
  5. var cnj_re = /CGINJS/
  6. var cnj_ment = "'CGINJS' 가 있는 문자열이 있으면 TRUE (대/소문자 구분)nn변수 : " + cnj_re;
  7. if (cnj_re.test("When Cgi Met Javascript = CginJs.Com") == true) {
  8. alert(cnj_ment + "nn문자열이 있군요(true)");
  9. } else {
  10. alert(cnj_ment + "nn문자열이 없군요(fail)");
  11. }
  12. }
  13. //-->
  14. </SCRIPT>
  15. <input type="button" name="cnj_text" value="확인" omClick="cnj_regexp()"> 



정규 표현식(Regular Expression) 사용예제 3

  1. <SCRIPT LANGUAGE="JavaScript">
  2. <!--
  3. function cnj_regexp() {
  4. // 대소문자 구분없이 해당 문자 또는 문자열을 검색할 경우 끝에 i 를 붙인다.
  5. // 'cginjs' 또는'CGINJS' 가 있는 문자열 모두가 있으면 TRUE (대/소문자 구분)
  6. var cnj_re = /CGINJS/i
  7. var cnj_ment = "'cginjs' 또는 'CGINJS' 가 있는 문자열 모두가 있으면 TRUE (대/소문자 구분)nn변수 : " + cnj_re;
  8. if (cnj_re.test("When Cgi Met Javascript = CginJs.Com") == true) {
  9. alert(cnj_ment + "nn문자열이 있군요(true)");
  10. } else {
  11. alert(cnj_ment + "nn문자열이 없군요(fail)");
  12. }
  13. }
  14. //-->
  15. </SCRIPT>
  16. <input type="button" name="cnj_text" value="확인" omClick="cnj_regexp()"> 


정규 표현식(Regular Expression) 사용예제 4

  1. <SCRIPT LANGUAGE="JavaScript">
  2. <!--
  3. function cnj_regexp() {
  4. // 여러개의 이어지는 내용들을 검색할 경우는 '-' 를 넣어 표현한다.
  5. // 'a' 에서 'z' 까지중 하나만 있으면 모두가 TRUE (대소문자 구분)
  6. var cnj_re = /[a-z]/
  7. var cnj_ment = "'a' 에서 'z' 까지중 하나만 있으면 모두가 TRUE (대소문자 구분)nn변수 : " + cnj_re;
  8. if (cnj_re.test("When Cgi Met Javascript = CginJs.Com") == true) {
  9. alert(cnj_ment + "nn문자열이 있군요(true)");
  10. } else {
  11. alert(cnj_ment + "nn문자열이 없군요(fail)");
  12. }
  13. }
  14. //-->
  15. </SCRIPT>
  16. <input type="button" name="cnj_text" value="확인" omClick="cnj_regexp()">


정규 표현식(Regular Expression) 사용예제 5

  1. <SCRIPT LANGUAGE="JavaScript">
  2. <!--
  3. function cnj_regexp() {
  4. // | 는 OR 같은 의미
  5. // 여러가지의 문자 또는 문자열을 검색할 경우 '|' 이용
  6. // 'x' 또는 'y' 또는 'z' 가 있는 문자열 모두가 TRUE (대소문자 구분)
  7. var cnj_re = /x|y|z/
  8. var cnj_ment = "'x' 또는 'y' 또는 'z' 가 있는 문자열 모두가 TRUE (대소문자 구분)nn변수 : " + cnj_re;
  9. if (cnj_re.test("When Cgi Met Javascript = CginJs.Com") == true) {
  10. alert(cnj_ment + "nn문자열이 있군요(true)");
  11. } else {
  12. alert(cnj_ment + "nn문자열이 없군요(fail)");
  13. }
  14. }
  15. //-->
  16. </SCRIPT>
  17. <input type="button" name="cnj_text" value="확인" omClick="cnj_regexp()"> 


정규 표현식(Regular Expression) 사용예제 6

  1. <SCRIPT LANGUAGE="JavaScript">
  2. <!--
  3. function cnj_regexp() {
  4. // | 는 OR 같은 의미
  5. // 여러가지의 문자 또는 문자열을 검색할 경우 '|' 이용
  6. // 'a' 에서 'z' 까지 또는 '0' 에서 '9' 까지중 하나만 있으면 모두가 TRUE (대소문자 구분)
  7. var cnj_re = /[a-z]|[0-9]/
  8. var cnj_ment = "'a' 에서 'z' 까지 또는 '0' 에서 '9' 까지중 하나만 있으면 모두가 TRUE (대소문자 구분)nn변수 : " + cnj_re;
  9. if (cnj_re.test("When Cgi Met Javascript = CginJs.Com") == true) {
  10. alert(cnj_ment + "nn문자열이 있군요(true)");
  11. } else {
  12. alert(cnj_ment + "nn문자열이 없군요(fail)");
  13. }
  14. }
  15. //-->
  16. </SCRIPT>
  17. <input type="button" name="cnj_text" value="확인" omClick="cnj_regexp()">


정규 표현식(Regular Expression) 사용예제 7

  1. <SCRIPT LANGUAGE="JavaScript">
  2. <!--
  3. function cnj_regexp() {
  4. // 해당 문자또는 문자열이 없는 경우를 검색할 경우 브래킷('[', ']') 안에 '^' 를 넣는다.
  5. // 'a' 에서 'z' 까지의 문자가 아닌 문자가 있을 경우 TRUE (대소문자 구분)
  6. var cnj_re = /[^a-z]/
  7. var cnj_ment = "'a' 에서 'z' 까지의 문자가 아닌 문자가 있을 경우 TRUE (대소문자 구분)nn변수 : " + cnj_re;
  8. if (cnj_re.test("When Cgi Met Javascript = CginJs.Com") == true) {
  9. alert(cnj_ment + "nn문자열이 있군요(true)");
  10. } else {
  11. alert(cnj_ment + "nn문자열이 없군요(fail)");
  12. }
  13. }
  14. //-->
  15. </SCRIPT>
  16. <input type="button" name="cnj_text" value="확인" omClick="cnj_regexp()"> 


정규 표현식(Regular Expression) 사용예제 8

  1. <SCRIPT LANGUAGE="JavaScript">
  2. <!--
  3. function cnj_regexp() {
  4. // 문자열의 첫번째 글자가 일치해야할 경우는 '^' 를 브래킷('[', ']') 밖에 넣는다
  5. // 'a' 에서 'z' 까지의 문자로 시작하는 문자열일 겨우 TRUE (대소문자 구분)
  6. var cnj_re = /^[a-z]/
  7. var cnj_ment = "'a' 에서 'z' 까지의 문자로 시작하는 문자열일 겨우 TRUE (대소문자 구분)nn변수 : " + cnj_re;
  8. if (cnj_re.test("When Cgi Met Javascript = CginJs.Com") == true) {
  9. alert(cnj_ment + "nn문자열이 있군요(true)");
  10. } else {
  11. alert(cnj_ment + "nn문자열이 없군요(fail)");
  12. }
  13. }
  14. //-->
  15. </SCRIPT>
  16. <input type="button" name="cnj_text" value="확인" omClick="cnj_regexp()">


정규 표현식(Regular Expression) 사용예제 9

  1. <SCRIPT LANGUAGE="JavaScript">
  2. <!--
  3. function cnj_regexp() {
  4. // 문자열의 끝쪽 글자가 해당 문자 또는 문자열과 일치해야할 경우는 '$' 를 넣는다.
  5. // 'a' 에서 'z' 까지의 문자로 끝나는 문자열일 겨우 TRUE (대소문자 구분)
  6. var cnj_re = /[a-z]$/
  7. var cnj_ment = "'a' 에서 'z' 까지의 문자로 끝나는 문자열일 겨우 TRUE (대소문자 구분)nn변수 : " + cnj_re;
  8. if (cnj_re.test("When Cgi Met Javascript = CginJs.Com") == true) {
  9. alert(cnj_ment + "nn문자열이 있군요(true)");
  10. } else {
  11. alert(cnj_ment + "nn문자열이 없군요(fail)");
  12. }
  13. }
  14. //-->
  15. </SCRIPT>
  16. <input type="button" name="cnj_text" value="확인" omClick="cnj_regexp()">


 정규 표현식(Regular Expression) 사용예제 10

  1. <SCRIPT LANGUAGE="JavaScript">
  2. <!--
  3. function cnj_regexp() {
  4. // 특수문자('', '^', '$', '*', '+', '?', '.', '(', ')', '|', '{', '}', '[', ']')를 검색할 경우는 '' 를 넣는다.
  5. // '' 가 있는 문자열일 겨우 TRUE (대소문자 구분)
  6. var cnj_re = /\/
  7. var cnj_ment = "'' 가 있는 문자열일 겨우 TRUE (대소문자 구분)nn변수 : " + cnj_re;
  8. if (cnj_re.test("When Cgi Met Javascript = CginJs.Com") == true) {
  9. alert(cnj_ment + "nn문자열이 있군요(true)");
  10. } else {
  11. alert(cnj_ment + "nn문자열이 없군요(fail)");
  12. }
  13. }
  14. //-->
  15. </SCRIPT>
  16. <input type="button" name="cnj_text" value="확인" omClick="cnj_regexp()"> 


Posted by 엘키 엘키

댓글을 달아 주세요

언어적인 기능으로 보면 Javascript는 완벽하게 private, public, static을 구현한다. 게다가 구현 후에 작동방식도 거의 비슷하다.

1. private 프로퍼티, 메쏘드의 선언
     ClassA=function(){

          var a=30;

          var test=function(){

                return a;

          }

     }


위의 예처럼 클래스 내부에서 var를 통해 생성한 메쏘드 혹은 프로퍼티는 내부에서만 호출할 수 있는 private이 된다.

당연한 얘기지만 Javascript의 구조상 private로 선언된 프로퍼티나 메쏘드는 prototype을 통해 상속했든 소유로 상속했든 다른 객체에서 불러낼 수 없다. 따라서 프레임웍을 짤 작정으로 부모클래스를 만들 생각이라면 var로 선언해서는 안된다(자식이 전혀 이용할 수 없다)


2. public 프로퍼티, 메쏘드의 선언
     ClassA=function(){

          this.a=30;

          this.test=function(){

                return this.a;

          }

     }

public의 경우는 this. 키워드를 이용하면 손쉽게 구현된다. public는 외부에서 자유롭게 호출할 수 있을뿐만 아니라 상속한 자식객체에서도 불러쓸 수 있다. 자식객체가 public 프로퍼티나 메쏘드를 덮어쓰면 아무런 통지 없이 override된다. 따라서 public으로 선언된 모든 프로퍼티와 메쏘드는 override키워드가 들어가 있는 것이나 다름없다.

 


3. static 프로퍼티, 메쏘드의 선언
     ClassA=function(){

     }

     ClassA.a=30;

     ClassA.test=function(){

           return ClassA.a;

     }

클래스 선언 외부에서 프로퍼티와 메쏘드를 추가하게 되면 이는 Static이 된다. 다른 OOP언어들과 마찬가지로 static메쏘드 내에는 오직 static프로퍼티나 전역속성의 값만 포함할 수 있다.


4. 사용시 이슈가 되는 부분


    - private을 상속시키고 싶을 때
       private는 오직 해당 클래스 내부에서만 유효하다. 따라서 자식객체도 사용할 수 없다(이건 바꿀 수 없는 현실..)
       여기에 대해 나는 '__' 이름규칙을 암묵적으로 사용하고 있다.

       ClassA=function(){

            this.__a=30;

            this.__test=function(){

                  return this.__a;

            }

       }

       선언 자체야 public이 되어 당연히 상속되고 호출도 가능하지만 '__'라는 이름 제약때문에 실수로 호출하지 않는다.

     - private프로퍼티와 public 메쏘드의 조합

       이건 처음부터 아무런 문제없이 동작함으로 걱정없이 아래와같이 사용하면 된다. 하지만 상속이 되지 않는건 언제나 주의!
       ClassA=function(){

            var a=30;

            this.test=function(){

                  return a;

            }

       }
       예컨데 classA에서는 전혀 문제없지만 classB.prototype=new ClassA(); 한 경우 test()를 하게 되면 a가 존재하지 않아 에러!

 

     - 부모의 public 속성이 자식에게 공유되는 문제

       매우 심각한 문제로 반드시!! 회피방안을 생각해둬야한다. 
       내장객체, 사용자정의객체가 프로퍼티에 할당되면 값이 아니라 레퍼런스(포인터)가 잡혀 별도의 자식 instance에서 공유하게 된다.
       ClassA=function(){

            this.a=new Array();

       }

       ClassB=function(){

            this.set=function(val){

                   this.a.push(val)

            }

            this.get=function(){

                   return this.a.length;

            }

       }

       ClassB.prototype=new ClassA();
       var test1=new ClassB();

       var test2=new ClassB();

       test1.set();
       alert(test2.get()); // 1을 반환함
       위 소스를 보면 classA에서 선언된 a값엔 Array객체가 들어있는데 자식객체인 ClassB에서는 별도로 선언한 적이 없기 때문에

       ClassB의 인스턴스인 test1,test2에서 a가 잡고 있는 동일한 Array객체를 참조하게된다.
       결과적으로 test1쪽의 a에 push를 했음에도 불구하고 자동으로 같은 객체를 가르치고 있는 test2의 a도 갱신된 꼴이 된다.

       * 해법1 : 객체가 프로퍼티의 값으로 올 때는 반드시 초기화 함수를 부모객체가 지원해야한다. 이것을 보다 일반화하여 init등의 
                    이름으로 통일해두면 좋다. 위의 샘플의 일반적인 해법은 아래와 같다.
       ClassA=function(){

            this.initA=function(){

                   this.a=new Array();

            }

       }

       ClassB=function(){

            this.initA();

            this.set=function(val){

                   this.a.push(val)

            }

            this.get=function(){

                   return this.a.length;

            }

       }

       ClassB.prototype=new ClassA();
       이와 같은 선언을 하면 ClassB가 생성시에 명시적으로 ClassA의 속성을 지정하기 때문에 중복문제가 제거된다.
       * 해법2 : 보다 근원적인 해법은 자식객체가 명시적으로 부모생성자를 호출하는 것이다. call와 apply메쏘드를 통해 기본 지원된다.
       ClassA=function(){

            this.a=new Array();

       }

       ClassB=function(){

            ClassA.call(this);

            this.set=function(val){

                   this.a.push(val)

            }

            this.get=function(){

                   return this.a.length;

            }

       }

       ClassB.prototype=new ClassA();
       훨씬 깔끔하기도 하고 매우 일반적이기도 하다. call과 apply에 대해서는 따로 자세히 쓰지 않겠다.



출처: http://blog.naver.com/hika00?Redirect=Log&logNo=150029057576

Posted by 엘키 엘키

댓글을 달아 주세요

사내 보안 강화를 위해 패스워드를 변경했습니다.

그러고 나니 특수문자가 먹지 않더군요.

해당 문제를 위해 ^와 "문자열"로, 특수 문자 문제를 해결했습니다.

기본적으로 배치 파일 내에서, 루비, TCP/IP 등 여러 경로를 통해서 스크립트가 실행되는데, 그 중에서도 배치와 루비에서 실행 문자열이 결정되는 구조입니다.
이 과정에서의 문제 해결을 위해 다음 내용을 참고했습니다..


References

http://www.robvanderwoude.com/escapechars.php


Escape Characters

All DOS versions interpret certain characters before executing a command.
Some well know examples are the percent sign ( % ), and the redirection symbols ( < | > ).

Windows 95/98 and NT, and OS/2 too, also interpret double quotes ( " ) and ampersands ( & ), as shown in the Conditional Execution page.

In batch files, the percent sign may be "escaped" by using a double percent sign ( %% ).
That way, a single percent sign will be used as literal within the command line, instead of being furter interpreted.

In Windows 95/98 and NT, and OS/2 too, redirection symbols may be escaped by placing them between double quotes ( ">" ).
However, the quotes themselves will be passed to the command too, unlike the double percent sign.

Windows NT and OS/2 also allow the use of carets ( ^ ) to escape special characters. Even linefeeds can be escaped this way, as is shown in the Useless Tips page.

If you intend to "nest" commands with escaped characters, you may need to escape the escape character itself too.
In general, that won't make it any easier to read or debug your batch files, however.

Since the introduction of delayed variable expansion a new challenge is to escape exclamation marks, the "delayed" version of the percent sign.
Unlike percent signs, that can be escaped by doubling them, exclamation marks cannot be escaped by adding an extra exclamation mark.
Nor does a caret befor the exclamation mark work, unless quoted (i.e. ECHO ^! will fail to display an exclamation mark, whereas ECHO "^!" will display a quoted exclamation mark: "!").

Jaime Ramos sent me this link where the solution can be found: use ^^!.

The trick is that a single caret will be used to escape the exclamation mark in the firt "pass" of command line interpretation, but delayed variable expansion adds a second "pass" where the exclamation mark will be interpreted. If you don't get it, never mind, just remember the double caret before the exclamation mark.

To Be Investigated

Recently I discovered that (in Windows 7) with ECHO commands, an entire line can often be escaped with a single ASCII character 26 (Ctrl+Z or EOF, End Of File) as the first character to be ECHOed.
Only the > character may sometimes still be interpreted as "redirect to ..."

Summary

Escape Characters
Character to be escapedEscape SequenceRemark
%%%May not always be required in doublequoted strings, just try
^^^May not always be required in doublequoted strings, but it won't hurt
&^&
<^<
>^>
|^|
'^'Required only in the FOR /F "subject" (i.e. between the parenthesis), unless backq is used
`^`Required only in the FOR /F "subject" (i.e. between the parenthesis), if backq is used
,^,Required only in the FOR /F "subject" (i.e. between the parenthesis), even in doublequoted strings
;^;
=^=
(^(
)^)
!^^!Required only when delayed variable expansion is active
\\\Required only in the regex pattern of FINDSTR
[\[
]\]
"\"

Syntax : Escape Characters, Delimiters and Quotes

Using "Double Quotes"

If a single parameter contains spaces, you can still pass it as one item by surrounding in "quotes" - this works well for long filenames.

If a parameter is used to supply a filename like this:

    MyBatch.cmd "C:\Program Files\My Data File.txt"

This parameters will be:

   %0 =MyBatch
%1 ="C:\Program Files\My Data File.txt"

To launch a batch script with spaces in the Program Path requiring "quotes"

CMD /k ""c:\batch files\test.cmd" "Parameter 1 with space" "Parameter2 with space""

Removing Quotes

A common method of removing quotes from a variable is the following:

   :: Remove quotes
   SET _string=###%_string%###
   SET _string=%_string:"###=%
   SET _string=%_string:###"=%
   SET _string=%_string:###=%

Unfortunately this will fail if the variable is NULL.
Here are some batch routines to remove quotes.

Working without Quotes

Without surrounding quotes, a long filename will be passed as %1 %2 %3...

   MyBatch C:\Program Files\My Data File.txt

To refer to the pathname above use %* rather than %1 %2 %3 - the %* will cover all parameters - even if there are more than %9

You can apply Extended Filename syntax to %* with the following workaround:

  @ECHO OFF
  SET _params=%*

  :: pass params to a subroutine
  CALL :sub "%_params%" 
  GOTO :eof

  :sub 
  :: Now display just the filename (not path)
  ECHO %~n1

Delimiters

Delimiters separate one parameter from the next ( they split the command line up into words)
Parameters are normally separated by spaces, but any of the following are also valid delimiters.

Comma , 
Semicolon ;
Equals = 
Space 
Tab 

Notice that although / and - are commonly used to separate command options, they are absent from the list above. This is because batch file parameters are passed to CMD.exe which can accept it's own parameters (which are invoked using / and - )

Most commands will accept any of the delimiters above with the exception of FOR - the FOR command assumes a SPACE delimiter - for anything else you need to specify the `delims=' option.

When using the TAB character as a delimiter be aware that many text editors will insert a TAB as a series of SPACEs.

When you use %* to refer to all parameters, the value returned will include the delimiters, under NT 4.0 this will include the leading space, under Win 2000 and above it won't.

Escape Character

  ^  Escape character.

Adding the escape character before a command symbol allows it to be treated as ordinary text. 
When piping or redirecting any of these charcters you should prefix with the escape character: \ & | > < ^

     e.g.  ^\  ^&  ^|  ^>  ^<  ^^ 

The escape character can be used to escape itself ^^ (meaning don’t treat the first ^ as an escape character), so you are escaping the escape character:

The characters in bold get escaped: 
    ^&  =>   &
  ^^^&  =>  ^&
^^^^^&  => ^^& 

Some commands (e.g. REG and FINDSTR) use the standard escape character of \ (as used by C, Python, SQL, bash and many other languages.)
The \ escape can cause problems when combined with NTFS paths that contain a trailing backslash.

For example the string "C:\Scripts\" would be interpreted as "C:\Scripts

Workarounds are to add a second backspace escape character or a space
"C:\Scripts\\"
 or "C:\Scripts\ "

“All the best stories in the world are but one story in reality - the story of escape. It is the only thing which interests us all and at all times, how to escape” - A. C. Benson

Related:

SETLOCAL EnableDelayedExpansion - More examples, particularly for HTML.
Long Filenames and NTFS - Valid characters in filenames
cmd Syntax
Powershell Escape Character


'Scripts > Batch' 카테고리의 다른 글

문자열 내에 특수 문자가 있는 경우  (0) 2013.09.10
Posted by 엘키 엘키

댓글을 달아 주세요

이전버튼 1 2 이전버튼

블로그 이미지
Software Engineer
엘키

공지사항

Yesterday31
Today29
Total1,605,483

달력

 « |  » 2020.8
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

글 보관함