/(\/\*[\s\S]*?\*\/|\/{2,}[^\r\n]*(?:\r\n|\r|\n|)|"(?:\\[\s\S]|[^"\r\n\\])*"|'(?:\\[\s\S]|[^'\r\n\\])*'|(?:(?:\/(?!\*)(?:\\.|[^\/\r\n\\])+\/)(?:[gimy]{0,4}|\b)(?=\s*(?:(?!\s*[\/\\<>*+%`^"'\w$-])[^\/\\<>*+%`^'"@({[\w$-]|===?|!==?|\|\||[&][&]|\/[*\/]|[,.;:!?)}\]\r\n]|$)))|<([^\s>]*)[^>]*>[\s\S]*?<\/\2>|>>>=?|<<=|===|!==|>>=|\+\+(?=\+)|\-\-(?=\-)|[=!<>*+\/&|^-]=|[&][&]|\|\||\+\+|\-\-|<<|>>|0(?:[xX][0-9a-fA-F]+|[0-7]+)|\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|[1-9]\d*|[-+\/%*=&|^~<>!?:,;@()\\[\].{}]|(?![\r\n])\s+|(?:\r\n|\r|\n)|[^\s+\/%*=&|^~<>!?:,;@()\\[\].{}'"-]+)/gこれがパターンです。
例えば、
/* comment */ var regex = /[\/\\"']*/g; var str = "hoge\"fuga'\ piyo"; // 'comment' var arr = [ 0x0FFF, 1e8, 0, 12345, 3.524603890386048e+24, 0.0006215, 0666 // (classic mode) ]; var i = 0; var e4x = <>{{///*E4X*///}}</>; var xml = <root><hoge fuga="piyo" /></root>; var ほげ = '/*"ほ//げ"*/'; var $var = re.test(str) && arr[2] || (i+++i) === 1;このコードを文字列として code.match(pattern) すると、以下の要素を持った配列が得られます。
0: /* comment */ 1: 2: var 3: 4: regex 5: 6: = 7: 8: /[\/\\"']*/g 9: ; 10: 11: var 12: 13: str 14: 15: = 16: 17: "hoge\"fuga'\ piyo" 18: ; 19: 20: // 'comment' 21: var 22: 23: arr 24: 25: = 26: 27: [ 28: 29: 30: 0x0FFF 31: , 32: 33: 1e8 34: , 35: 36: 0 37: , 38: 39: 12345 40: , 41: 42: 43: 3.524603890386048e+24 44: , 45: 46: 47: 0.0006215 48: , 49: 50: 0666 51: 52: ] 53: ; 54: 55: var 56: 57: i 58: 59: = 60: 61: 0 62: ; 63: 64: var 65: 66: e4x 67: 68: = 69: 70: <>{{///*E4X*///}}</> 71: ; 72: 73: var 74: 75: xml 76: 77: = 78: 79: <root><hoge fuga="piyo" /></root> 80: ; 81: 82: var 83: 84: ほげ 85: 86: = 87: 88: '/*"ほ//げ"*/' 89: ; 90: 91: var 92: 93: $var 94: 95: = 96: 97: re 98: . 99: test 100: ( 101: str 102: ) 103: 104: && 105: 106: arr 107: [ 108: 2 109: ] 110: 111: || 112: 113: ( 114: i 115: ++ 116: + 117: i 118: ) 119: 120: === 121: 122: 1 123: ;そもそもシンタックスハイライトのほうが崩れてる…。
jsFiddle でテストできます。
文字列は、改行の前にバックスラッシュ (\) がある場合も対応してみました。
セミコロン挿入もあって、スペースと改行は区別されます。
E4X はシンプルなのだけ対応してます。
var x = <root<div id={(function() { return '</root>' ? 'hoge' : 'fuga'; }())}></root>こういうのは無理っぽい。あとネストとか。
match() に g つけて match(/(...)/g) がこんな便利だなんて…。