js 정규 표현 식 문법 강조
그렇다면 두 명의 대신 차 탄산 코발트 와 Barret Lee 의 문법 적 하 이 라이트 실현 을 분석 해 보 자.
Barret Lee 의 이'몇 가지 작은 예 를 들 어 정규 표현 식 하 이 라이트 하 이 라 이 트 를 실현 하 는 방법 을 알려 드 립 니 다.'부터 말씀 드 리 겠 습 니 다.
이전에 보 았 을 때 신기 하 다 고 만 느 꼈 다.특히 아래 의 그 한 걸음 한 걸음 일치 하 는 예 는 더욱 패기 가 새 는 것 을 측정 했다.그러나 작 가 는 헤 어 지 는 것 은 단지 시범 을 보 여 주 는 것 일 뿐 이 단계 가 무엇 과 일치 하 는 지 직관 적 으로 볼 수 있다 고 말 했다.그렇지 않 으 면 한 걸음 에 일치 하 는 것 이 완성 되 고 무슨 일이 일 어 났 는 지 모 르 고 처리 할 수 있다 고 말 했다.그의 정규 를 살 펴 보 자
(/^\s+|\s+$/) //
(/(["'])(?:\\.|[^\\
])*?\1/) //
(/\/(?!\*|span).+\/(?!span)[gim]*/) // span ,
(/(\/\/.*|\/\*[\S\s]+?\*\/)/) //
(/(\*\s*)(@\w+)(?=\s*)/) //
(/\b(break|continue|do|for|in|function|if|else|return|switch|throw|try|catch|finally|var|while|with|case|new|typeof|instance|delete|void|Object|Array|String|Number|Boolean|Function|RegExp|Date|Math|window|document|navigator|location|true|false|null|undefined|NaN)\b/) //
콧수염 형 은 바퀴 를 다시 만 들 고 싶 지 않 은 지 이런 바퀴 를 어떻게 만 드 는 지 알 고 싶 었 을 뿐 이 었 다.그래서 그 는 이 물건 을 찍 으 면 바로 멈 추고 깊이 있 게 처리 하지 않 아 거 칠 게 만 들 었 다.물론 나 도 그 가 뭐라고 말 하 는 것 은 아니다.단지 간단하게 평론 할 뿐이다.왜냐하면 우수한 문법 하 이 라이트 플러그 인 은 스스로 반복 해서 만 들 필요 가 없고 원 리 를 배우 면 된다.다음 탄산 코발트 라 는'정규 표현 식 의 JavaScript 코드 하 이 라 이 트 를 어떻게 실현 합 니까?'을 분석 해 보 겠 습 니 다.사실 이 편 은 이미 매우 상세 하 게 분석 되 었 습 니 다.저 는 간단하게 보충 설명 할 수 밖 에 없습니다.차 탄산 코 발 트 는 항상 생각 이 엄밀 합 니 다.이 글 을 읽 기 전에 저 는 한 시간 넘 게 봤 습 니 다.대충 볼 수 밖 에 없 었 습 니 다.이번에 다시 한 번 분석 한 다음 에 제 가 한 번 실 현 했 습 니 다.저 에 게 반나절 이 걸 렸 습 니 다.하지만 아주 가치 가 있 습 니 다.진심으로 많은 것 을 배 웠 습 니 다.
우선 대체적인 논 리 를 살 펴 보 자.
(\/\/.*|\/\*[\S\s]+?\*\/) //
((["'])(?:\\.|[^\\
])*?\3) //
\b(break|continue|do|for|in|function|if|else|return|switch|this|throw|try|catch|finally|var|while|with|case|new|typeof|instance|delete|void)\b //
\b(Object|Array|String|Number|Boolean|Function|RegExp|Date|Math|window|document|navigator|location)\b //
\b(true|false)\b //
\b(null|undefined|NaN)\b // , 。
(?:[^\W\d]|\$)[\$\w]* //
(0[xX][0-9a-fA-F]+|\d+(?:\.\d+)?(?:[eE]\d+)?) // ( , )
(?:[^\)\]\}]|^)(\/(?!\*)(?:\\.|[^\\\/
])+?\/[gim]*) //
[\S\s] //
원문 에서 마지막[\S\s]에 대한 설명:우 리 는 모든 문자 에 일치 해 야 합 니 다.HTML 전의 가 필요 하기 때문이다.그리고 아래 에 상세 한 코드 가 있 습 니 다.이것 은 매우 좋 은 문장 이다.나 는 앞 뒤 를 적어도 10 번 은 보지 못 했 고 이틀 전에 야 거의 완전히 이해 하지 못 했다.
그러나 이 코드 는 문자열 이 접 힌 줄 과 일치 하지 않 고 문자열 이 최적화 되 어 있 는 작은 흠 이 있 습 니 다.
그리고 숫자 매 칭 이 전면적 이지 않 으 면 0xff,12.34,1e3 등 몇 가지 유형 만 일치 할 수 있 습 니 다.예 를 들 어.123 12.3e+3 등 형식 은 일치 하지 않 습 니 다.그리고 키워드 순 서 는 조금 이라도 최적화 할 수 있 을 것 같 습 니 다.전통 적 인 NFA 엔진 은 왼쪽 에서 오른쪽으로 만 일치 하기 때문에 다음 분기 의 작업 을 중단 합 니 다.그래서 가장 자주 등장 하 는 키 워드 를 앞 에 놓 으 면 일부 성능 을 향상 시 킬 수 있다.마지막 으로 new RegExp 가 좋 습 니 다.이렇게 하면 코드 의 양 이 많은 코드 성능 이 향상 되 는 것 입 니 다.
다음은 제 정규 와 간단 한 demo 를 드 리 겠 습 니 다.사실은 차 탄산 코발트 소스 코드 에 대한 최적화 일 뿐이다.)먼저 정규 부분 보기:
(\/\/.*|\/\*[\s\S]*?\*\/) //
("(?:[^"\\]|\\[\s\S])*"|'(?:[^'\\]|\\[\s\S])*') //
\b(true|false|null|undefined|NaN)\b // , ,
\b(var|for|if|else|return|this|while|new|function|switch|case|typeof|do|in|throw|try|catch|finally|with|instance|delete|void|break|continue)\b // ,
\b(document|Date|Math|window|Object|location|navigator|Array|String|Number|Boolean|Function|RegExp)\b // ,
(?:[^\W\d]|\$)[\$\w]* //
(0[xX][0-9a-fA-F]+|\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|\.\d+(?:[eE][+-]?\d+)?) // ,
(?:^|[^\)\]\}])(\/(?!\*)(?:\\.|[^\\\/
])+?\/[gim]*) // , , ,
[\s\S] //
불 과 빈 값 을 합 쳐 그룹 을 나 눈 후 정규 그룹 을 최적화 시 켜 그 보다 두 개의 그룹 을 줄 였 다.그 는 2,3 은 문자열 로 나 누 었 다.왜냐하면(")앞의 따옴표 가 잡 혔 고 나의 정 규 는 이렇게 하지 않 았 기 때문이다.이것(true|false|null|undefined|NaN)한 그룹 에 두 는 것 을 좋아 하지 않 는 다 면,나 누 어도 되 고,같은 그룹 인지 아 닌 지 는 착색 을 구분 하기 위 한 것 일 뿐 입 니 다.sublime text 아래 true|false|null|undefined|NaN 은 모두 같은 색 이 고 notepad+는 true|false 만 착색 되 었 습 니 다.저 는 그냥 하하 라 고 말 하고 싶 습 니 다.됐어,하마터면 예 를 들 뻔 했 어.나 는 많은 사람들 이 이 를 보기 전에 이미 꺼 졌 거나 스크롤 바 만 내리 고 꺼 졌 다 고 믿는다.하지만 이 글 을 쓴 것 은 진지 하 게 보 는 친구 들 에 게 한 사람 만 보면 헛 되 지 않 을 것 이 라 고 생각 합 니 다.예:
//
/**
*
* @date 2014-05-12 22:24:37
* @name
*/
var str1 = "123\"456";
var str2 = '123\'456';
var str3 = "123\
456";
var num = 123;
var arr = [12, 12.34, .12, 1e3, 1e+3, 1e-3, 12.34e3, 12.34e+3, 12.34e-3, .1234e3];
var arr = ["12", "12.34", '.12, 1e3', '1e+3, 1e-3', '12.34e3, 12.34e+3, 12.34e-3', ".1234e3"];
var arr = [/12", "12.34/, /"12\/34"/];
for (var i=0; i<1e3; i++) {
var node = document.getElementById("a"+i);
arr.push(node);
}
function test () {
return true;
}
test();
(function(window, undefined) {
var _re_js = new RegExp('(\\/\\/.*|\\/\\*[\\s\\S]*?\\*\\/)|("(?:[^"\\\\]|\\\\[\\s\\S])*"|\'(?:[^\'\\\\]|\\\\[\\s\\S])*\')|\\b(true|false|null|undefined|NaN)\\b|\\b(var|for|if|else|return|this|while|new|function|switch|case|typeof|do|in|throw|try|catch|finally|with|instance|delete|void|break|continue)\\b|\\b(document|Date|Math|window|Object|location|navigator|Array|String|Number|Boolean|Function|RegExp)\\b|(?:[^\\W\\d]|\\$)[\\$\\w]*|(0[xX][0-9a-fA-F]+|\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?|\\.\\d+(?:[eE][+-]?\\d+)?)|(?:^|[^\\)\\]\\}])(\\/(?!\\*)(?:\\\\.|[^\\\\\\/\
])+?\\/[gim]*)|[\\s\\S]', 'g');
function prettify(node) {
var code = node.innerHTML.replace(/\r
|[\r
]/g, "
").replace(/^\s+|\s+$/g, "");
code = code.replace(_re_js, function() {
var s, a = arguments;
for (var i = 1; i <= 7; i++) {
if (s = a[i]) {
s = htmlEncode(s);
switch (i) {
case 1: // com
return '<span class="com">' + s + '</span>';
case 2: // str
return '<span class="str">' + s + '</span>';
case 3: //true|false|null|undefined|NaN val
return '<span class="val">' + s + '</span>';
case 4: // kwd
return '<span class="kwd">' + s + '</span>';
case 5: // obj
return '<span class="obj">' + s + '</span>';
case 6: // num
return '<span class="num">' + s + '</span>';
case 7: // reg
return htmlEncode(a[0]).replace(s, '<span class="reg">' + s + '</span>');
}
}
}
return htmlEncode(a[0]);
});
code = code.replace(/(?:\s*\*\s*|(?: )*\*(?: )*)(@\w+)\b/g, ' * <span class="comkey">$1</span>') //
.replace(/(\w+)(\s*\(|(?: )*\()|(\w+)(\s*=\s*function|(?: )*=(?: )*function)/g, '<span class="func">$1</span>$2') //
return code;
}
function htmlEncode(str) {
var i, s = {
//"&": /&/g,
""": /"/g,
"'": /'/g,
"<": //g,
"<br>": /
/g,
" ": / /g,
" ": /\t/g
};
for (i in s) {
str = str.replace(s[i], i);
}
return str;
}
window.prettify = prettify;
})(window);
너 희 는 아래 의 코드 로 테스트 를 진행 할 수 있다.코드:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
<style>
/* */
*{font-size:12px;}
code{word-break:break-all;}
.com {color:#008000;} /* */
.comkey {color:#FFA500;} /* */
.str {color:#808080;} /* */
.val {color:#000080;} /* true|false|null|undefined|NaN */
.kwd {color:#000080;font:bold 12px 'comic sans ms', sans-serif;} /* */
.obj {color:#000080;} /* */
.num {color:#FF0000;} /* */
.reg {color:#8000FF;} /* */
.func {color:#A355B9;} /* */
</style>
</head>
<body>
<code id="regdemon">
//
/**
*
* @date 2014-05-12 22:24:37
* @name
*/
var str1 = "123\"456";
var str2 = '123\'456';
var str3 = "123\
456";
var num = 123;
var arr = [12, 12.34, .12, 1e3, 1e+3, 1e-3, 12.34e3, 12.34e+3, 12.34e-3, .1234e3];
var arr = ["12", "12.34", '.12, 1e3', '1e+3, 1e-3', '12.34e3, 12.34e+3, 12.34e-3', ".1234e3"];
var arr = [/12", "12.34/, /"12\/34"/];
for (var i=0; i<1e3; i++) {
var node = document.getElementById("a"+i);
arr.push(node);
}
function test () {
return true;
}
test();
(function(window, undefined) {
var _re_js = new RegExp('(\\/\\/.*|\\/\\*[\\s\\S]*?\\*\\/)|("(?:[^"\\\\]|\\\\[\\s\\S])*"|\'(?:[^\'\\\\]|\\\\[\\s\\S])*\')|\\b(true|false|null|undefined|NaN)\\b|\\b(var|for|if|else|return|this|while|new|function|switch|case|typeof|do|in|throw|try|catch|finally|with|instance|delete|void|break|continue)\\b|\\b(document|Date|Math|window|Object|location|navigator|Array|String|Number|Boolean|Function|RegExp)\\b|(?:[^\\W\\d]|\\$)[\\$\\w]*|(0[xX][0-9a-fA-F]+|\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?|\\.\\d+(?:[eE][+-]?\\d+)?)|(?:^|[^\\)\\]\\}])(\\/(?!\\*)(?:\\\\.|[^\\\\\\/\
])+?\\/[gim]*)|[\\s\\S]', 'g');
function prettify(node) {
var code = node.innerHTML.replace(/\r
|[\r
]/g, "
").replace(/^\s+|\s+$/g, "");
code = code.replace(_re_js, function() {
var s, a = arguments;
for (var i = 1; i <= 7; i++) {
if (s = a[i]) {
s = htmlEncode(s);
switch (i) {
case 1: // com
return '<span class="com">' + s + '</span>';
case 2: // str
return '<span class="str">' + s + '</span>';
case 3: //true|false|null|undefined|NaN val
return '<span class="val">' + s + '</span>';
case 4: // kwd
return '<span class="kwd">' + s + '</span>';
case 5: // obj
return '<span class="obj">' + s + '</span>';
case 6: // num
return '<span class="num">' + s + '</span>';
case 7: // reg
return htmlEncode(a[0]).replace(s, '<span class="reg">' + s + '</span>');
}
}
}
return htmlEncode(a[0]);
});
code = code.replace(/(?:\s*\*\s*|(?: )*\*(?: )*)(@\w+)\b/g, ' * <span class="comkey">$1</span>') //
.replace(/(\w+)(\s*\(|(?: )*\()|(\w+)(\s*=\s*function|(?: )*=(?: )*function)/g, '<span class="func">$1</span>$2') //
return code;
}
function htmlEncode(str) {
var i, s = {
//"&": /&/g,
""": /"/g,
"'": /'/g,
"<": /</g,
">": />/g,
"<br>": /
/g,
" ": / /g,
" ": /\t/g
};
for (i in s) {
str = str.replace(s[i], i);
}
return str;
}
window.prettify = prettify;
})(window);
</code>
<script>
(function(window, undefined) {
var _re_js = new RegExp('(\\/\\/.*|\\/\\*[\\s\\S]*?\\*\\/)|("(?:[^"\\\\]|\\\\[\\s\\S])*"|\'(?:[^\'\\\\]|\\\\[\\s\\S])*\')|\\b(true|false|null|undefined|NaN)\\b|\\b(var|for|if|else|return|this|while|new|function|switch|case|typeof|do|in|throw|try|catch|finally|with|instance|delete|void|break|continue)\\b|\\b(document|Date|Math|window|Object|location|navigator|Array|String|Number|Boolean|Function|RegExp)\\b|(?:[^\\W\\d]|\\$)[\\$\\w]*|(0[xX][0-9a-fA-F]+|\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?|\\.\\d+(?:[eE][+-]?\\d+)?)|(?:^|[^\\)\\]\\}])(\\/(?!\\*)(?:\\\\.|[^\\\\\\/\
])+?\\/[gim]*)|[\\s\\S]', 'g');
function prettify(node) {
var code = node.innerHTML.replace(/\r
|[\r
]/g, "
").replace(/^\s+|\s+$/g, "");
code = code.replace(_re_js, function() {
var s, a = arguments;
for (var i = 1; i <= 7; i++) {
if (s = a[i]) {
s = htmlEncode(s);
switch (i) {
case 1: // com
return '<span class="com">' + s + '</span>';
case 2: // str
return '<span class="str">' + s + '</span>';
case 3: //true|false|null|undefined|NaN val
return '<span class="val">' + s + '</span>';
case 4: // kwd
return '<span class="kwd">' + s + '</span>';
case 5: // obj
return '<span class="obj">' + s + '</span>';
case 6: // num
return '<span class="num">' + s + '</span>';
case 7: // reg
return htmlEncode(a[0]).replace(s, '<span class="reg">' + s + '</span>');
}
}
}
return htmlEncode(a[0]);
});
code = code.replace(/(?:\s*\*\s*|(?: )*\*(?: )*)(@\w+)\b/g, ' * <span class="comkey">$1</span>') //
.replace(/(\w+)(\s*\(|(?: )*\()|(\w+)(\s*=\s*function|(?: )*=(?: )*function)/g, '<span class="func">$1</span>$2') //
return code;
}
function htmlEncode(str) {
var i, s = {
//"&": /&/g,
""": /"/g,
"'": /'/g,
"<": /</g,
">": />/g,
"<br>": /
/g,
" ": / /g,
" ": /\t/g
};
for (i in s) {
str = str.replace(s[i], i);
}
return str;
}
window.prettify = prettify;
})(window);
var code = document.getElementById("regdemon");
code.innerHTML = prettify(code);
</script>
</body>
</html>
콧수염 형 과 차 탄산 코발트 두 가지 사고방식 을 결합 한 결과 지금 은 비교적 완벽 해 졌 다.호환성 같은 것 은 아직 테스트 를 하지 않 았 고 테스트 할 필요 도 없다.나 도 각종 문법의 하 이 라 이 트 를 스스로 쓸 생각 은 없다.너무 피곤 하 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
awk 상용 명령awk 는 모든 입력 줄 을 하나의 기록 으로 인식 하고 그 줄 의 모든 단어 도 메 인 을 하나의 필드 로 인식 합 니 다. ARGC 명령 줄 에 awk 스 크 립 트 가 들 어 오 는 매개...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.