亚洲有码Av一区二区三区_国产高清啪啪免费视频_69色视频国产_国产成人人人爆出白浆_国产精品自在线拍国_一本久久伊人热热精品无码_午夜性刺激在线看免费带字幕_助力高品质欧美狂喷水_亚洲精品日韩无码_精品无码一区二区三区蜜臀_麻豆高清国产AV_熟妇人素无码中文字幕_亚洲a级片在线观看_国产欧美日韩三区_99国产成人高清在线观看

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運營的一線實戰(zhàn)洞察。

正則可視化調(diào)試工具Rea:解析器與回溯軌跡全解析

正則可視化調(diào)試工具Rea:解析器與回溯軌跡全解析 正則表達式這玩意兒寫的時候感覺自己就是語言學(xué)家調(diào) bug 的時候又覺得自己像個算命先生。尤其面對那種一長串(?...)、(?!...)、嵌套分組、堆了七八個量詞的老古董正則你很難說清楚它到底在干什么、為什么這一段匹配上了、那一段又吞了字符。去年我就在這種狀態(tài)里憋了很久最后決定動手寫一個工具叫ReaRegular Expression Assistant。它的核心能力不是幫你“驗證正則對不對”而是把正則從字符串到匹配結(jié)果的每一步都拆開以語法樹、匹配軌跡、回溯路徑的方式攤在眼前。這篇文章就把 Rea 的設(shè)計思路、解析器實現(xiàn)、執(zhí)行引擎可視化以及我實測中踩過的幾個深坑完整梳理一遍。如果你也經(jīng)常被復(fù)雜正則困住或者想做一個類似的“看得見執(zhí)行過程”的開發(fā)者工具這篇應(yīng)該能給你不少能直接用的方案。1. 為什么我動手寫 Rea市面上沒有講清楚正則的調(diào)試工具1.1 正則難讀的本質(zhì)你不是不會寫是看不到它的結(jié)構(gòu)很多人覺得正則難是因為直接把一串字符當成了“規(guī)則本身”。但正則其實是一門微型語言它從用戶輸入到最終匹配至少要經(jīng)過兩層解釋第一層是字符串層也就是你肉眼看到的那串字符第二層是語法層它要把*、、{}、[]、()、^、$這些東西識別成量詞、字符組、分組、斷言第三層才是執(zhí)行層也就是用語法樹去和目標文本做狀態(tài)匹配。問題在于市面上絕大多數(shù)正則工具只給你輸入框、測試文本、匹配結(jié)果列表三個東西。你看到的是“匹配了”或者“沒匹配”但看不到匹配引擎在中間到底走了哪條路。比如這個很常見的密碼校驗正則^(?.*\d)(?.*[a-z])(?.*[A-Z]).{8,16}$它能在大多數(shù)工具里正常工作但如果你想知道“為什么第二個斷言失敗”工具只會在原地轉(zhuǎn)一圈給個淡淡的“無匹配”。正則本身成了一個黑盒調(diào)試就變成了盲猜。Rea 想解決的就是這件事把黑盒打開。它會把正則解析成語法樹按分組、量詞、斷言的邏輯層級展開然后按執(zhí)行引擎的每一步把當前匹配位置、捕獲組快照、嘗試過的分支、回溯跳轉(zhuǎn)都記錄下來最后在界面上用“步驟列表 文本進度條 回溯連線”的方式回放。這樣一來正則不再是猜謎而是有跡可循的調(diào)試對象。1.2 一個案例說明現(xiàn)有工具的不足我在某個日志清洗項目里遇到過一條線上規(guī)則^(?:[^,]),(\d{4}-\d{2}-\d{2}),(.*)$意圖是從逗號分隔的日志行里取出日期和剩余內(nèi)容。工具測試時規(guī)則是通的但到了生產(chǎn)里有一批行死活匹配不上。后來逐行看發(fā)現(xiàn)某些日志的時間字段里多了個空格比如2024-01-02 03:04:05更關(guān)鍵的是前面有個字段本身包含逗號導(dǎo)致[^,]把后面的結(jié)構(gòu)全打亂了。這種問題用現(xiàn)成工具很難定位。你看到“沒匹配”三個字但到底是因為日期格式錯了、字段分隔符不對、還是分組量詞吃掉了不該吃的字符沒有執(zhí)行軌跡你只能繼續(xù)加日志、改正則、再測反復(fù)試錯。Rea 的定位就是把這個調(diào)試過程從“試”變成“看”讓引擎每走一步都留痕。1.3 Rea 的目標用戶和使用方式Rea 主要面向幾類人常年寫復(fù)雜正則的后端、數(shù)據(jù)開發(fā)需要在規(guī)則提交前快速確認執(zhí)行路徑做爬蟲、日志解析、網(wǎng)絡(luò)安全策略的工程師正則往往就是核心邏輯搞錯一次就全線崩帶新人的團隊可以把 Rea 當教學(xué)工具展示什么是回溯、什么是零寬斷言、為什么貪婪匹配會“吞掉”后面的部分想自己實現(xiàn)迷你正則引擎的人Rea 的解析和執(zhí)行代碼本身就是一份可以拆著看的參考。它不是用來替代常規(guī)正則測試器的。常規(guī)工具負責“結(jié)果對不對”Rea 負責“為什么對、為什么錯、瓶頸在哪”。在實際使用里這兩者配合起來效率最高。2. Rea 的架構(gòu)設(shè)計為什么我要自己寫一個解析器而不是復(fù)用現(xiàn)成正則引擎2.1 四層架構(gòu)詞法層、語法層、執(zhí)行層、渲染層Rea 的整體結(jié)構(gòu)分成四層每一層職責單一數(shù)據(jù)傳輸方向也很明確。層級主要職責輸入輸出詞法層把正則字符串切成有意義的最小單元正則源字符串Token 數(shù)組語法層把 Token 按優(yōu)先級組裝成 ASTToken 數(shù)組語法樹節(jié)點執(zhí)行層用 AST 模擬正則匹配過程并記錄步驟AST 待測文本步驟記錄數(shù)組渲染層把 AST 和步驟記錄可視化步驟記錄 AST界面交互展示這樣分層的好處是每一層都可以單獨測試。詞法層不關(guān)心語法對不對語法層不關(guān)心文本匹配執(zhí)行層只關(guān)心狀態(tài)遷移渲染層只關(guān)心怎么把數(shù)據(jù)畫出來。后面我排查引擎行為不一致的問題時基本都能快速定位到具體某層而不是整鍋粥一塊煮。2.2 為什么選 TypeScript 而不是 Python 后端 網(wǎng)頁前端一開始我確實想過用 Python 做解析引擎再包一層 Web 接口前端用 Canvas 畫軌跡。但很快否了。原因有三個第一Rea 的核心交互發(fā)生在瀏覽器里從輸入正則到看到軌跡最好是在一個頁面內(nèi)完成不要有網(wǎng)絡(luò)往返。純前端的 TypeScript 方案最干凈打開頁面即用也能直接做成離線工具。第二正則的方言差異很大。JavaScript 自己就有 ECMAScript 正則語義如果后端用 Python 的regex庫做解析那 Rea 展示的行為和用戶瀏覽器里的實際行為就會出現(xiàn)差異。干脆直接用 TypeScript 按 ECMAScript 語義實現(xiàn)一個小型引擎反而能讓“工具行為”和“用戶環(huán)境行為”保持更近。第三調(diào)試工具本身得容易調(diào)試。TypeScript 有完整的類型定義AST 節(jié)點的結(jié)構(gòu)、步驟記錄的數(shù)據(jù)結(jié)構(gòu)都可以用類型約束起來改起來不容易改出隱蔽的運行時錯誤。2.3 為什么不直接復(fù)用現(xiàn)成的解析庫社區(qū)里確實有很好的正則解析庫比如regexpp、regexp-tree這些能生成標準 AST也省很多事。但我最終還是自己寫了解析器。原因很實際現(xiàn)成庫給出的 AST 偏向“規(guī)范正確”但不太照顧“可視化友好”。Rea 的語法樹既要做結(jié)構(gòu)展示又要和執(zhí)行引擎的步驟一一對應(yīng)。我希望每個節(jié)點上都掛著stepIndex、capturesAffected這類執(zhí)行期信息還要在渲染時能給分組、量詞、斷言分別上色。自己生成 AST意味著我能完全控制節(jié)點類型和副作用標注。當然自己寫解析器不是逞能。我的實現(xiàn)目標很明確覆蓋 ECMAScript 正則的常見語法子集包括字符類、分組、命名捕獲、非捕獲分組、前瞻斷言、后顧斷言、量詞和分支就好。像復(fù)雜的vflag Unicode 集合運算這種極少數(shù)用到的特性我直接選擇不支持并在界面上給出“暫不支持”的提示。與其做個半吊子支持不如明確邊界把核心路徑打磨穩(wěn)。2.4 執(zhí)行引擎的定位不是追求性能而是追求“可觀察”Rea 的執(zhí)行引擎不需要像原生 V8 正則引擎那樣快它的核心指標是每個決策都要能記錄下來。所以我實現(xiàn)的是基于 AST 的遞歸回溯模擬器每個節(jié)點進入、嘗試、成功、失敗、回溯都會產(chǎn)生一條步驟記錄。這種實現(xiàn)方式在很短文本上性能完全夠用。因此我在 Rea 里留了一條默認保護線待測文本長度超過 5000 字符或者步驟數(shù)超過 5 萬步就停止執(zhí)行并給出提示。這個限制不是偷懶是考慮到瀏覽器渲染壓力同時也是為了讓用戶意識到一個正則跑出幾萬步本身就是需要警惕的信號。3. 解析器實現(xiàn)從一串字符串到一棵語法樹3.1 詞法層先切出最小單元詞法層做的事情很簡單把源字符串掃一遍根據(jù)當前字符是不是\、是不是[、是不是(來切出不同類型 token。我定義的基礎(chǔ) token 類型大概是這樣的type TokenType | char // 普通字符 | escape // \d \w \s \n \uXXXX 等轉(zhuǎn)義 | classStart // [ | classEnd // ] | groupStart // ( | groupEnd // ) | charClassEnd? // 用不到 | quantifier // * ? { | alternation // | | anchor // ^ $ | lookahead // (? (?! 等 | lookbehind // (? (?!詞法需要特別注意轉(zhuǎn)義字符。比如\d應(yīng)該作為一個Escapetoken它的值是d類型是“數(shù)字類”\.也是一個Escapetoken但語義是“轉(zhuǎn)義后的點字符”。轉(zhuǎn)義后面跟著什么字符決定了這個 token 到底代表一類字符還是代表一個普通字面字符這個判斷放到語法層再做會更清晰。3.2 語法層用遞歸下降處理優(yōu)先級正則的優(yōu)先級從高到低大約是原子字符、字符類、分組 量詞 連接順序拼接 分支|。因此我用了遞歸下降解析器四個方法互相調(diào)用class RegexParser { private tokens: Token[]; private pos: number 0; parse(): Node { const expr this.parseAlternation(); if (this.pos ! this.tokens.length) { throw new Error(Unexpected token at position ${this.pos}); } return expr; } private parseAlternation(): Node { const children [this.parseSequence()]; while (this.match(alternation)) { children.push(this.parseSequence()); } return children.length 1 ? children[0] : { type: Alternation, children, captures: [] }; } private parseSequence(): Node { const children: Node[] []; while (!this.check(groupEnd) !this.check(alternation) !this.isEnd()) { children.push(this.parseRepeat()); } return children.length 1 ? children[0] : { type: Sequence, children }; } private parseRepeat(): Node { const atom this.parseAtom(); if (this.check(quantifier)) { const q this.eat(quantifier) as QuantifierToken; return { type: Repeat, atom, min: q.min, max: q.max, greedy: q.greedy, }; } return atom; } private parseAtom(): Node { const token this.peek(); // 根據(jù) token 類型分別處理普通字符、轉(zhuǎn)義類、字符類、分組、斷言 } }這個結(jié)構(gòu)很經(jīng)典但對正則來說有幾個容易寫錯的地方。最典型的是分組解析左括號(后面可能是?、?!、?:、?name、?、?!這些尾巴必須在同一層處理干凈。我把所有分組入口都集合在parseAtom里private parseGroup(): GroupNode { this.eat(groupStart); const start this.prevToken(); let type: GroupType capturing; let name: string | undefined; if (this.peek().type flag) { const flag this.eat(flag); if (flag.value ?:) type noncapturing; if (flag.value ?) type lookahead; // 肯定前瞻 if (flag.value ?!) type negativeLookahead; if (flag.value ?) type lookbehind; if (flag.value ?!) type negativeLookbehind; // ?name 要單獨解析 } const body this.parseAlternation(); this.eat(groupEnd); return { type: Group, groupType: type, name, body, // 捕獲組編號在整棵 AST 構(gòu)建完成后統(tǒng)一分配 }; }這里有一個非常容易踩的坑命名捕獲組(?name...)的前綴?和后顧斷言(?...)的前綴?只差一個字符。詞法層如果分開處理必須做到最長的匹配優(yōu)先。我在詞法掃描時看到?會把后面的字符一起拿到看第三個字符是、!還是別的。如果是或!就是后顧斷言否則就當作命名分組開始。3.3 捕獲組編號的分配時機正則里捕獲組編號有其固定規(guī)則按(在正則字符串中出現(xiàn)的順序編號從左到右遇到普通捕獲組就遞增。非捕獲組(?:...)不參與編號但后顧斷言、前瞻斷言里的捕獲組卻參與編號。Rea 的做法是先完整生成 AST然后做一次后序遍歷給分組節(jié)點統(tǒng)一分配捕獲組索引。索引分配的信息會保存在 AST 節(jié)點上執(zhí)行引擎在記錄捕獲組快照時直接讀取。這個設(shè)計避免了在解析過程中動態(tài)編號造成的狀態(tài)混亂尤其當分組嵌套很深時后序遍歷比邊解析邊編號要穩(wěn)得多。3.4 字符類內(nèi)部的“第二套語法”字符類[...]內(nèi)部和外部的語法規(guī)則完全不同。普通上下文里.就是任意字符就是量詞但在[]里大部分元字符都失去特殊含義只是加號本身-在中間是范圍連接符在首尾或轉(zhuǎn)義后是普通字符。^出現(xiàn)在[后面第一個位置表示取反出現(xiàn)在其他地方就是普通字符。Rea 的詞法層會單獨維護一個“字符類上下文模式”。進入[后詞法不再識別量詞、分支、分組而只識別普通字符、轉(zhuǎn)義字符、范圍符號-、以及結(jié)尾的]。這樣函數(shù)雖然多了一個狀態(tài)分支但后續(xù)解析邏輯清爽很多。4. 可視化執(zhí)行引擎把回溯變成看得見的軌跡4.1 回溯的本質(zhì)是選擇點的撤銷回溯是正則引擎最核心、也最讓人頭疼的機制。很多人的概念是“匹配失敗了就回溯”其實回溯發(fā)生在“當前路徑匹配不下去時回到最近一個還能選其他路的選擇點”。想理解回溯可以把正則匹配想象成走迷宮。你到了一個岔路口左邊墻上有標記“這是分叉點”你選擇走左岔路。走了幾十米發(fā)現(xiàn)是死胡同于是退回到岔路口撿起沒走過的右岔路再走。回溯的成本不一定高但如果在同一個分叉點反復(fù)試、試完又回到上個分叉點、疊了好幾層量詞路徑數(shù)量就會爆炸。Rea 的可視化引擎核心就是記錄每個分叉點的“打開/關(guān)閉”動作。每當一個節(jié)點嘗試一個分支就產(chǎn)生一條try步驟如果分支失敗就產(chǎn)生一條backtrack步驟。這樣用戶能看到引擎到底做了幾次選擇、每次選擇消耗了什么字符。4.2 步驟記錄器的數(shù)據(jù)結(jié)構(gòu)執(zhí)行引擎在遞歸回溯過程中會產(chǎn)生海量中間信息但如果全部記錄性能會很差。Rea 對記錄內(nèi)容做了取舍不記錄每一次字符比較而是記錄“節(jié)點級事件”。一個CharNode的比較只記錄一次成功或失敗一個量詞的每次重復(fù)循環(huán)都記錄為一次迭代一個斷言節(jié)點記錄其成功/失敗以及結(jié)束位置。核心步驟類型如下interface Step { type: enter | try | match | fail | backtrack | end; nodeId: number; // AST 節(jié)點唯一 id nodeLabel: string; // 便于展示的節(jié)點描述 position: number; // 進入該節(jié)點時的文本位置 nextPosition: number; // 離開該節(jié)點后的文本位置 captureSnapshot: CaptureSnapshot; // 當前捕獲組快照 stepIndex: number; // 全局遞增步驟號 depth: number; // 遞歸深度渲染時用來做縮進 }捕獲組快照不能每次都深拷貝整個對象那樣文本稍長就會內(nèi)存爆炸。我采用了“按需記錄”的方式只在進入捕獲組失敗、退出捕獲組、或者回溯發(fā)生時記錄當前捕獲組狀態(tài)。每一步事件都帶一個引用指向“上一次發(fā)生了捕獲變化的快照”渲染層再按需合并出完整狀態(tài)。這個優(yōu)化在回放幾千步的匹配過程時非常關(guān)鍵。4.3 執(zhí)行器代碼骨架執(zhí)行器本質(zhì)上就是遍歷 AST 的遞歸函數(shù)。以一個簡化版為例function tryNode(node: Node, pos: number, ctx: MatchContext): number | null { switch (node.type) { case Char: { const ok ctx.text[pos] node.value; recordStep(try, node, pos, ok ? pos 1 : pos, ctx); return ok ? pos 1 : null; } case Star: case Plus: case Repeat: { return tryQuantifier(node, pos, ctx); } case Sequence: { let cur pos; for (const child of node.children) { const next tryNode(child, cur, ctx); if (next null) { recordStep(backtrack, node, cur, cur, ctx); return null; } cur next; } return cur; } case Group: { if (node.groupType capturing) { ctx.captureStart(node.index); } const endPos tryNode(node.body, pos, ctx); if (node.groupType capturing endPos ! null) { ctx.captureEnd(node.index, endPos); } return endPos; } default: return null; } }注意這里Sequence一旦遇到子節(jié)點失敗直接返回失敗由上層決定是否回溯。真正選擇點的管理放在Alternation和Repeat節(jié)點里。比如Alternation需要依次嘗試每個子分支失敗后記錄一次backtrack再試下一個分支case Alternation: { for (const child of node.children) { const result tryNode(child, pos, ctx); if (result ! null) return result; recordStep(backtrack, node, pos, pos, ctx); } return null; }量詞的邏輯更麻煩。因為貪婪量詞會先盡可能多匹配匹配到上限后再逐漸讓出字符做后續(xù)匹配。這個“讓出字符”就是回溯在量詞上的表現(xiàn)。Rea 在tryQuantifier里用一個循環(huán)先按貪婪策略吞字符吞到吞不下為止然后把一次次的“吞入”和后續(xù)“回吐”都記錄下來function tryQuantifier(node: RepeatNode, pos: number, ctx: MatchContext): number | null { let count 0; let cur pos; const attempts: number[] []; while (count (node.max ?? Infinity) (node.min 0 || count node.min)) { const next tryNode(node.atom, cur, ctx); if (next null) break; attempts.push(cur); cur next; count; } // 貪婪時先嘗試繼續(xù)多匹配 while (count (node.max ?? Infinity)) { const next tryNode(node.atom, cur, ctx); if (next null) break; attempts.push(cur); cur next; count; } // 回退嘗試減少重復(fù)次數(shù) while (count node.min) { if (node.min 0 || count node.min) { const rest tryNode(node.next, cur, ctx); // 簡化真實的遞歸結(jié)構(gòu)需要掛載 next 指針 if (rest ! null) return rest; recordStep(backtrack, node, cur, cur, ctx); } count--; cur count 0 ? attempts[count - 1] : pos; } return null; }實際引擎里node.next不像上面這么簡單因為 AST 是樹結(jié)構(gòu)處理量詞時需要把“匹配完重復(fù)內(nèi)容后的剩余部分”作為 continuation 傳入否則很難正確回溯。我在實現(xiàn)里給每個節(jié)點增加next指針結(jié)構(gòu)上變成一個“AST 鏈式 continuation”的組合執(zhí)行器在量詞回退時就能把當前位置交給后續(xù)節(jié)點繼續(xù)嘗試。node.next這個概念是 Rea 能正確可視化回溯的關(guān)鍵。如果不做 continuation只靠遞歸返回值來回退那么一旦量詞內(nèi)部失敗上層就傻眼了根本不知道還有“少吞一個字符再試后續(xù)”這一條路。4.4 一個完整案例的回放拿a(b|c)*d匹配abccd來演示。這個正則的邏輯是先匹配a然后(b|c)*可以匹配零個或多個b或c最后匹配一個d。在 Rea 步驟列表里你會看到近似這樣的事件序列步驟事件節(jié)點位置說明0enterSequence0進入整個表達式1matchChara0 - 1成功消耗 a2enterRepeat (bc)*13tryGroup (bc)1 - 24tryGroup (bc)2 - 35tryGroup (bc)3 - 46tryGroup (bc)4 - 57backtrackRepeat (bc)*5 - 48matchChard4 - 5后續(xù) d 匹配成功9endSequence5整體匹配完成這里第 7 步就是關(guān)鍵。用戶從前到后看會覺得“明明文本第三個字符就是 d為什么引擎還要先吞掉再回退”因為正則里的貪婪量詞在不了解后續(xù)節(jié)點的情況下只能先盡可能多吞吞到吞不動了再交還。這個“交還”動作就是回溯也是很多正則性能問題的來源。通過 Rea 的步驟列表新手能直觀看到*在*和后面如果還跟著其他必須匹配的內(nèi)容很容易出現(xiàn)“先多吃再吐出來”的現(xiàn)象。如果后續(xù)內(nèi)容很多回溯次數(shù)會呈指數(shù)級增長。5. 實測中的坑正則語義和 Rea 表現(xiàn)不一致的五個修復(fù)5.1 斷言和普通節(jié)點對“當前匹配位置”的處理完全不同剛開始實現(xiàn)斷言時我的執(zhí)行器統(tǒng)一用“節(jié)點結(jié)束位置”來推進position。這在普通字符、分組、量詞上沒問題但碰到(?...)、(?...)就錯了。斷言不會消耗字符它從左到右檢查內(nèi)部子表達式能不能匹配能匹配就返回成功但匹配位置始終保持在斷言開始的位置。我第一次實測時發(fā)現(xiàn)a(?b)c匹配abc的時候Rea 展示的步驟是“a 之后斷言 b 成功c 直接從位置 2 開始匹配”而斷言的內(nèi)部匹配“從位置 1 到位置 2 消耗了 b”也被記錄成了普通消耗。這就導(dǎo)致用戶看到的位置推進和實際引擎行為對不上。修復(fù)方式是給斷言節(jié)點單獨立一條規(guī)則內(nèi)部執(zhí)行完成后位置必須恢復(fù)為斷言入口位置。Rea 的步驟記錄里還會額外標記“零寬斷言不消耗字符”讓用戶一眼看懂為什么斷言里的 b 沒有影響后面的 c。5.2 捕獲組編號在非捕獲組和后顧斷言里的偏移正則里有一個新手極其容易寫錯的地方(?:...)不算捕獲組編號但前瞻/后顧斷言里的(...)要算。比如(?(a))\1中\(zhòng)1指的是前瞻里的捕獲組(?:(b))\2則是非法的因為非捕獲組里即便有(b)編號也只會是 1不存在 2。Rea 的后序遍歷編號時只是在普通Group節(jié)點上遞增編號。但我一開始把斷言內(nèi)部的Group和后顧斷言內(nèi)部的子表達式也統(tǒng)一編號了這導(dǎo)致(?(a))b的捕獲組編號和原生引擎不一致。測試時我拿一個帶后顧斷言的復(fù)雜正則一對一對比連續(xù)錯了幾十步才意識到問題。后來我把“編號分配”和“執(zhí)行路徑”分開考慮只要 AST 節(jié)點是Group且類型為capturing無論它出現(xiàn)在斷言內(nèi)部還是普通分支都參與編號但執(zhí)行時斷言內(nèi)部的捕獲組快照要臨時保存斷言失敗時恢復(fù)原狀。這才能和原生語義保持一致。5.3 指數(shù)級回溯不能被當成普通步驟Rea 做到一半時我拿(a)$配一個aaaaaaaaaaaaaaaaaaaaaaaaX。這個正則自己會跑出天文數(shù)字一樣的步驟因為a可以分成很多組又可以讓每組重復(fù)多次幾乎每一種分組方式都要試一遍。如果引擎老老實實把所有步驟都記錄到數(shù)組里頁面直接卡死。這里我設(shè)置了一個非常務(wù)實的保護步驟數(shù)超過 50000 就中止執(zhí)行并且單獨標記“檢測到疑似災(zāi)難性回溯”。用戶看到的現(xiàn)象不是普通的失敗列表而是一條醒目的警告當前正則可能在更長文本上導(dǎo)致嚴重性能問題。這個警告本身就是調(diào)試結(jié)論遠比“無匹配”三個字有價值。從實現(xiàn)上講50000 步的保護閾值并不是隨便定的。我實測過普通復(fù)雜正則在一個幾十字符的文本上通常只跑幾百到幾千步50000 足以覆蓋絕大多數(shù)正常場景超過這個數(shù)大概率是正則本身出了問題。5.4 字符類中]和-的邊界沒有想象中簡單我一開始處理[]時過于想當然在字符類里遇到]就結(jié)束遇到-就當作范圍連接符。但實際測[]-]這種正則時徹底翻車。這個正則是匹配]或-兩個字符之一的。它的結(jié)構(gòu)是[開始第一個字符是]但因為]緊跟在[后面所以它不應(yīng)該被視為結(jié)束符然后-是普通字符最后一個]才是結(jié)束符。詞法層必須知道“當前是不是緊跟在[或[^之后”。只有在跟在開始位置的字符才是普通字符否則才會作為結(jié)束符處理。類似地[a-]里的-在結(jié)尾沒有構(gòu)成范圍也只是普通字符。這些邊界情況在正則文檔里只有一兩句話在 Rea 里卻是一整組測試用例。5.5 命名分組和反向引用的映射關(guān)系Rea 支持(?name...)和\kname。一開始我把名字和編號映射關(guān)系存在一個全局 Map 里解析一個正則、清空一次。結(jié)果遇到命名分組在后顧斷言里、并且正則主體里還有同名分組時Map 被覆蓋了。雖然 ECMAScript 規(guī)范不允許同一個正則里出現(xiàn)重復(fù)的命名分組但執(zhí)行到斷言內(nèi)部時捕獲組狀態(tài)是嵌套的不能簡單使用同一個對象。我最后改成每個捕獲組快照包含兩份信息一份是編號索引到字符串位置的數(shù)組另一份是名字到編號的 Map。斷言執(zhí)行時這兩份數(shù)據(jù)一起進入獨立棧幀。這樣即使斷言內(nèi)部和外部都有命名分組回退時也不會互相污染。5.6 與原生正則行為對齊的驗證方法做這個工具最大的風險是自己實現(xiàn)了一個“看起來挺對”的引擎但實際行為和瀏覽器里的new RegExp不一致。那 Rea 不但沒用還會誤導(dǎo)人。所以 Rea 里內(nèi)置了一組對照測試把用戶輸入的正則先交給原生RegExp執(zhí)行一次拿到結(jié)果同時讓 Rea 自己的引擎執(zhí)行再比較兩者的匹配區(qū)間、捕獲組內(nèi)容是否一致。不一致時Rea 會在界面右下角彈出一條“與原生行為不一致”的提示并標出第一個出現(xiàn)差異的步驟位置。這個機制幫我在開發(fā)階段發(fā)現(xiàn)了很多隱蔽問題。比如$在 ECMAScript 里默認只匹配到文本末尾但如果設(shè)置了多行模式它還會匹配換行符之前的位置比如\b的“單詞邊界”邏輯在中文文本里和英文文本里的表現(xiàn)完全不同。這些如果不做對照測試靠人眼很難發(fā)現(xiàn)。6. Rea 在實際項目里的用法日志巡檢和新人培訓(xùn)6.1 用步驟回放定位日志正則的誤判我們后端有一段時間日志告警規(guī)則老出問題。有一條規(guī)則要過濾掉所有包含SECRET關(guān)鍵字的日志行正則寫成了^(?!.*SECRET).*$這條正則單獨的匹配結(jié)果看起來沒錯但它有一個隱藏性能問題負向前瞻里有個.*SECRET如果失敗后續(xù)的.*還要繼續(xù)跑。在幾萬行的日志流上跑正則引擎的回溯開銷會被放大。用 Rea 把一條幾百字符的日志樣本放進去回放會看到步驟數(shù)到了幾千步。原因就是負向前瞻在每個字符位置都做一次“往后找 SECRET”的嘗試找不到再前進一個字符重復(fù)執(zhí)行??吹竭@個軌跡之后我們把規(guī)則改成了先用indexOf做快速排除再在數(shù)據(jù)流里跑正則日志處理速度立刻上來一個數(shù)量級。Rea 不能直接替你優(yōu)化正則但老實地把每一步選擇攤開來看優(yōu)化點會自己浮出來。6.2 在代碼評審和規(guī)則變更前做“執(zhí)行軌跡審查”以前評審正則改動只能看 diff 里的正則字符串憑經(jīng)驗判斷“這樣改應(yīng)該沒問題”。有了 Rea 之后我們形成了一個小流程任何涉及復(fù)雜正則的改動都要附帶一張 Rea 生成的步驟概覽截圖至少包括分支嘗試次數(shù)、最大回溯深度、捕獲組命中次數(shù)這幾個指標。這樣做的好處是評審人不用逐字讀正則直接看數(shù)字就能判斷這次改動是不是引入了新的性能隱患。如果一次改動讓步驟數(shù)從 200 漲到 8000哪怕功能測試全過我也會打回去重新設(shè)計因為步驟數(shù)暴漲意味著后面文本一旦變長引擎遲早卡死。6.3 拿 Rea 給新人講清楚“貪婪與懶惰”的區(qū)別我經(jīng)常拿 Rea 給組里新人演示貪婪量詞和懶惰量詞的區(qū)別。比如.*?這個經(jīng)典寫法。很多測試器只告訴新人“懶惰量詞盡量少匹配”但說不清“盡量少”到底是怎么做到的。在 Rea 里跑a.*?b匹配axxbyyb能看到引擎先讓.*?匹配零個字符然后立刻嘗試匹配b失敗于是回退讓.*?多匹配一個字符再嘗試匹配b……重復(fù)這個過程直到找到第一個能接上b的位置。這個逐步“擠牙膏”的過程在步驟列表里一目了然比任何文字說明都直觀。6.4 可擴展的方向從匹配軌跡到自動生成解釋Rea 現(xiàn)在的核心是“展示軌跡”但后續(xù)可以往“解釋軌跡”方向走。語法樹已經(jīng)結(jié)構(gòu)化了執(zhí)行步驟也已經(jīng)標注了節(jié)點語義完全可以再加一個自然語言生成模塊把“當前位置嘗試匹配數(shù)字字符失敗回溯到量詞分支”翻譯成人話。如果能生成一句話“這個正則失敗在第 12 步因為第 3 個捕獲組沒有匹配到預(yù)期格式”那才是真正的正則老師。另一個擴展方向是正則簡化。通過 AST 分析出冗余的嵌套分組、重復(fù)的字符類、不可能匹配到的分支然后給出提示。這個方向有挑戰(zhàn)但對日常維護歷史正則的人來說價值巨大。7. 最后分享一點使用經(jīng)驗Rea 開發(fā)到現(xiàn)在我自己最深的體會是正則調(diào)試工具真正的價值不在于“多炫”而在于“把不確定性變成確定性”。以前遇到一個復(fù)雜正則我習(xí)慣先猜猜錯就再改改完再測循環(huán)往復(fù)。現(xiàn)在我會先把正則丟進 Rea看一眼它的執(zhí)行軌跡很多時候問題根源就在前 50 步里。如果你也想做個類似的東西我建議從一個小得多的范圍開始先支持字符、字符類、量詞、分組這四類把可視化做好再慢慢加斷言和反向引用。不要一上來就想著完整實現(xiàn) ECMAScript 全部特性否則大概率會被邊界情況拖死。再給一個小技巧Rea 的步驟記錄里我最??吹牟皇恰捌ヅ涑晒Α钡哪切┎襟E而是backtrack步驟?;厮菰蕉嗾f明正則的“決策”質(zhì)量越差越值得優(yōu)化。一個正則如果回溯步驟超過總步驟的 30%基本就該重寫了。這句話扔給團隊里的新人比講十分鐘理論都好用。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
91天天美女| 色呦色呦色精品| 性91| 91性高| 一本道综合色图| 精品国产91内射久久| 欧美偷| 操b网站亚洲无码| 精品久热| 日本午夜久久电影| 欧美精品成人在线播放| 91操熟女| 999综合网| 夜夜 中文视频rt| 天天干天天操天天拍| 综合影视国产无码| 九九热久久99精品re| 国内毛片四区| 日本二区不卡| 另类老少妇| 综合性视频99| 农村女一级毛卡片| 风韵犹存大大大大香蕉 | 97欧美色资源| 图色综合网| 久久久精品国产亚洲伊人| 欧美精品久久久久久久久88| av网页一区二区三区| 91啦人妻| 欧亚在线视频| 日韩av影片在线观看| 在线观看无码三级少妇| 岛国成人av在线播放网址| av在线一区二区三区| 综合久久久久久久综合网| 操屄日韩| 人人做,人人操,人人摸| 国产福利电影| 黄色人人| 久久色情| 99热导航| 久久久久久99999国产精品| 午夜精品人妻二区三区| 超碰97人人乐| 另类图片综合| 久久精品国产亚洲AV高清演员表| 日本黄色大片一级视频免费麻豆| 国产精品成人在线| 麻豆天美国美国产| 99re只有精品| 欧美极品| 国产精品呦一区二区三区| 懂色av色欲av蜜臀av| 欧美一区二区三区另类精品| 一级性爱aaaa| 欧美亚洲综合色| 嗯嗯,啊啊,国产精品| 97九色人妻| 夜夜操天天肏| 久热大香蕉网站| 九九九九九九九| 黄页av| 一起草三级AV电影在线观看 | 国产强奸乱伦xd| www.av在线视频| 精品性爱一二三区| 精品久久久久黄少妇| 亚洲色悠悠久久88| 国产99热| 国产女人成人精品视频| 久久少妇人妻| 精品国产一区探花在线观看| av日韩在线观看电影| 婷婷六月色| 五月天色图| 中出在线视频| 国产无码三级视频在线观看| 97色色色| 好爽视频在线观看| 99久久e免费热视| 熟女人妻av在线资源,黄色的资源| 久久久久网站-538在线视频-欧美永久乱码 | www国产天美久久久| 色色国产| 国产99999久久精品| 午夜小电影在线插入淫高潮| 日本99久久| 四虎884a| 热99这里有精品综合久久| 又黄又爽在线观看视频| 美女91色黄18| 操逼国产免费| 色九九九九| 九热中文字幕| 加勒比大香蕉视频在线| 国产熟女自拍| 久久人人爽爽人人爽人人片αV| 国产精品三级视频网站| 熟妇激情| 久久6热视频免费观看| 精品人妻夜夜草| 色九久| 一区二区三区欧美激情| 91成人社区| 精品黄色电影| 97这里都是精品| 国产强奸乱伦第1页| 九九综合色| 日本顶级天天操狠狠操夜夜操中文字幕 | 欧美日产国产在线成人第一区| 日日夜夜干| 久久精品国产97欧美精品亚洲| 国语对白露脸XXXXXX| 日本免费中文一区二区三区四区 | 国产a片操逼| 国产九月婷婷| 日本孕妇一区二区视频操逼免费看 | 韩国成人精品久久久免费看 | 欧美爱爱97| 九九内射在线| 97国产人人| 日本福利社| 天天干人人乐| 亚洲色堂免费视频| 欧州一区二区三区四区| 亚洲男人的天堂V| 96精品久久久久久久久久| 五月丁香影院| 日韩在线电影| 国产夜夜艹| 99国产精品| 超碰超碰欧美| 亚洲乱色熟女一区| 精品999日本| 熟女人妻一区二区三区| 啊啊啊啊好疼| 美女露胸露尿口| 日本国产亚洲一区在线观看| 色综合超碰超| 亚洲激情网| 玖草在线视频| 97色涩| 国产成人bd在线观看| 国产精品久久久久999| 久久久久久久久成人av解说| 97欧美日韩综合| av情色影音| 夜夜操美女| 精品高清牛人盗摄一区二区三区中文字幕A片免费在线观看 | 天天日美女的B| 凹凸视频特色日本特黄| 日韩欧美日韩| 97一区二区三区视频| www.色操逼| 亚洲少妇在线观看| www欧美91| 激情文学欧美| 婷婷伊人綜合中文字幕小说| 成人av福利在线观看| 午夜精品久久999热蜜桃介男人用| 插欧洲美女欧美精品| 亚洲久久久久| 破处bbq| 欧美亚男人的天堂| 国产18精品亚洲精品| 2021国产成人精品久久| 99热99re6国产在线播放| 尹人大香蕉视频在线| 久久精品国产99精品亚洲蜜...| 99re在线视频国产| 天天操av懂色| 国内三级自拍小视频在线观看| 亚洲阿v天堂在线| 久热大香蕉网站| 亚洲高潮少妇| 亚洲男人天堂2019| 婷婷色网| 亚洲天堂,男人| 91天堂色男人的天堂| 成人性爱免费播放| 思思热国产高清| 日曰骚久久精品| 玖玖爱一区在线| 蜜臀国产AV中文字幕| 久久精品店| 久久欲| 狠狠爱综合网| 777超碰| 亚洲色图欧美色图在线播放| 国产精品不卡一区二区三区| 极品粉嫩一区二区| 美女人妻色网站| 99精品热| 日日夜夜天天| 色99视频| 伊色综合天堂色97| 97精品一二区| 秋霞午夜视频一区二区| 欧洲亚洲人妻无码中字久久三区四区| 操人妻少妇中文 | 日日摸日日碰| 亚州欧美综合| 久九9精品| 嗯嗯啊啊视频一区二区三区| 成人天天看站长推荐| 熟妇亚洲一区二区三区| 九九九九九九亚洲| 久久婷婷在线观看视频| 亚洲精品一卡二卡三卡福利视频网站| 亚洲黄片免费在线播放| 国产精品免费久久久久久久久久| 国产三级在线现体验区| 人干人人人操人人摸| 亚洲国产成人精品久久久国产成人一区二区三.| 日韩性爱一级片| 大学生美女口爆| 欧美夜夜草视频| 国产高清吃奶免费视频网站| 国产一级高跟丝袜| 国产 无码 一区二区| www.大香| 丁香五月色情| 日韩内射视频| 韩日精品福利视频一区不卡在线免| 国产美女激情| 亚洲男人天堂视频| 91狠狠综合久久| 9久久精品| 2024年最新色情网站在线观看 | 日韩国产品视频中文字| 久草婷婷| 欧美日韩精品久久久久东北老熟妇| 日本不卡免费二区| 在线视频亚洲无码| 97任你吞精| 天天做天天爽| 91无摭挡| 女沟厕偷窥piss小便| 无码操逼视频一下| 五月丁香激情综合| 麻豆成人av| 91精品丝袜久久久久久| 北约熟女超碰| oumeisetu综合| 综合天天网| 亚洲自拍小说| 国产一级内射无挡观看| 久久丁香| 夜夜嗨老熟女AV一区二区三区| 国产97视频| 大香蕉黄色一级片免费看| 一起草精品人妻| www.操| julia ann久久| 日本操逼无码| 亚洲天堂区| 亚洲网污污污污| 91亚洲网| 综合激情婷婷| 91n免费处女| 99人妻| 国产女生在线| 素颜老阿姨乱情色| 高清有码一区二区| 久久超碰爱| 美女91色黄18| 99精品久久久久久久婷婷蜜桃| 人妻久热在线| 97亚洲综合在线| 3d成人精品一区二区| 好湿好紧好爽 视频| 亚洲图片视频小说| 亚洲最新av无码成人精品区 | 九九九精品成人免费视频小说| 国产一区二区在线播放,久久亚洲精品中文字幕第一区,亚洲精品在线中文字幕视频 | 成人免费看吃奶视频网站| 狠狠激情综合狠狠操中文字幕| 无码99| 96国产精品| 人妻 丝袜美腿 中文字幕| 精品视频123区小说区| 东京热91| 亚洲人人操| 夜夜黄| 欧美精品日韩一区二区| 91插B网站| 国产精品成人福利在线| 久久久无码精品人妻二区| 人人人人插| 久久久久9999妇女| 国产对白刺激视频| 五十路熟女,国产欧美精品区一区二区三区| 搡老熟女免费视频| 久久超碰亚洲人| 毛片一区二区| 极品粉嫩一区二区| 天堂俺去俺来也www久久婷婷| 欧美色图亚洲特色| 性色av大全| 1区2区3区中文字幕日韩| 天天伊人| 久精品无码av一区二免费国产在线观看| WWW.加勒比人妻一区不卡.com| 热99这里有精品综合久久 | 亚洲91网。| 91丨九色丨国产丨人妻在线| 99色婷婷中文字幕乱色| 国产一级作爱毛片| 超碰偷拍| 亚洲中文字幕妇伦久久| 欧美另类精品xxxx| 蜜乳AV一区二区三区四| 91亚洲欧美综合高清在线| 黄片www.| 男人的天堂网页| 亚洲97P| 亚洲熟女性高潮久久久| 欧中美三级一区二区三区| 天天日天天色| 国产精品 久久久精品一牛| 老司机久久| 亚洲天堂 视频你懂的| 96一区二区三区| 婷婷四五区| 小视频国产| 久久久九九| 欧美日韩m| 国产成年免费大片黄在线观看| 人人妻天天做天天爽| 开心五月激情网| 欧美日韩国产成人高清| 另类老少妇| 欧美色66| 久久怡红院| 成人免费毛片| 好属操| 91成人社区| 成人国产精品三级A片| 蜜臀久久99精品久久久| 碰超人人在线一区二区三区| 67914亚洲精品| 久久精品 六十路 熟女 欧美| 91丝袜在线视频| 亚洲 日本 一 二 三| 人人操人人操人人人操| 黄色成年| 伊人视频| 久久久111| 国产精品com| 无套内射人妻在线播放| 97碰碰日本乱偷人妻中文的| 大香樵伊人网| 久久內射| 精品国产一区二区三区av在线资源| 国产JDAV无码视频在线观看| 99热一区二区三区四区| 69丨亚洲丨精品丨入口免费播放| 四虎 精品 WWW| 天天躁日日躁AAAXX| 乱伦色图网址是多少| 农村少妇久久久久久久| 国产精品另类一区大香蕉| 欧美午夜色妇色鬼| 国产性感在线观看| 久久久久久久 九九九九九九九| 极品美女福利在线观看| 久思思热视频在线观看| 一个人免费视频观看在线WWW| 日本在线伊人啪啪| 亚洲成人AB| 91精品人妻五十路| 青青草日韩免费观看高清在线| 看黑丝美女操逼青青网站| 嗯啊不要啊在线 | 天堂麻豆天美| 天堂麻豆天美| 色999偷自拍拍| 久久久久久久少妇| 日本天堂网| 肥臀熟女福利视频一区二区| 中文字幕亚洲欧美在线不卡| 美女露胸露屁股| 看看小穴| 日产中文字幕2020| 欧美韩国你懂得在线 | 性久久| 永久免费av无码网站国产app| 操b在线观看| 国产精品爆乳懂色蜜乳| 亚洲欧洲日本精品中文a∨| 综合久久少妇中文字幕| 爱妃国产亚洲视频中文字幕| 可能人人看人人摸| 久久久亚洲欧美综合| 夜间福利片1000无码| AV无码久久久精品| 亚州伊人色综台| 天天肏美女| 男人的天堂激情| 超碰 另类 欧美| 一直超碰| 综合欧美色图| 18禁看网站一区| 久久国产乱子伦精品免费女人| 亚洲精品一二区| 99精品成人免费看| 婷婷五月天_亚洲小说欧美激情另类_精品久久国产字幕 | 欧美色91| 91精品人| 国产小黄片在线免费观看| 在线观看黄色电话| 99热精品在线| 蜜乳av一区二区三区四区不卡| 亚洲97网站| 婷婷五月天激情四射| 亚洲国产精品无码AV久久久| caoni国产亚洲av| 婷婷综合五月天| 亚洲限制级在线| 综合91网| 天天噜| 中国国产精品一区视频| 性吧在线视频| 久偷拍欧美日韩三区| 97色操| 日本人妻伦在线中文字幕| 男人a天堂手机在线版| 久久一二三四五六七八九区区区 | 淫荡网址| 日韩性爱网址| 久久动漫精品视频这里只有精品| 96久久久久久久| 99在线免费公开视频| 91Chinese在线| 97精品第3页| 易易A毛视频| 久久精品日韩| 人人澡人人爽人人精品| 欧美九九九九九| 亚洲精美粉嫩嫩泬在线观看 | 加勒比综合网| 亚洲.欧美.丝袜.中文.综合| 东北操逼| 性爱免费视频成人| 手机不卡视频不卡在线一二三区| 国际精品久久久| A V视频日本| 九久9热| 亚洲人妻精品一区二区| 333kkkk·亚洲com久久| 国产噜噜噜噜噜久久久久久久久| 日韩肏逼视频| 国产欧美伊人| 日韩欧美传媒一区国产| 色色色综合网| 97在线免费看视频| 婷婷综合久久| 97超级久久| 翔田千里av一区二区三区| 亚洲十八禁止| 玖玖玖玖精品国产剧情| 亚洲色悠悠久久88| 秋霞久久亚洲精品成人| 日韩噜噜69| 超碰国产精品无码| 人妻无码久久一区二区三区免费| 男女做爰猛烈动高潮A片免费应用| 25国产精品免费观看| 伊人网在线点播| 久久久成人国产精品无码| 热的中文 热的有码 热的国产| 岛国在线免费视频| 大香蕉啪啪啪啪在线| 老司机深夜18禁污污网站| 熟妇熟女一区二三区| 国产又粗又大硬免费色网视频| 91人人爽人人爽人人人,gav福利视频导航,日韩欧美亚洲国产字幕四区 | 亚洲av乱伦色图网站| 久久中久文96| 九九碰九九爱97超碰| 91痴汉| 韩日精品四区| 激情黄色片在线观看| 国产丝袜美腿美女麻豆| 国产综合网站在线播放 | 国产成人91一区二区三区| 久久99国产综合精品女同| 日本影视久久免费| 亚洲一区二区 麻豆传媒| www.久久最新地址| 人妻丝袜二区| 日本熟人妻中文字幕在线|...久久国产精品-国产精品_日本一区二区三区中文字幕 | 在线国产一区二区av| 国产外初女出血视频| 色欲天天综合网| 91天堂网| 日韩情色AV| 日韩成人性爱电影在线播放| 啊啊啊啊啊啊啊啊在线观看| 最新亚洲风情电影| 亚洲av影院在线观看| 色吊丝 日日骚 清纯唯美| 熟女啪啪视频| 午夜视频好爽啊| chaopen97久久| 人妻精品综合中文字幕在线| 3d成人精品一区二区| 91综合天天| 亚洲色交| 精品v1区| 五月婷婷啪啪| 黄色片,com| 欧美宗合网| 女人的天堂大香蕉网| 国产无套粉嫩白浆在| 日本成人在线不卡一区二区三区| 色www精品视频在线观看| 丰满人妻-区二区三区免费| 一二三四视频中文字幕在线看| 精品视频一区二区| 欧美韩国你懂得在线 | 欧美色图亚洲色,麻豆| 青青操97| 丁香色婷婷| www.av在线视频| 久久久久国产精品久久久| 久久6热精品99视频| 少妇蜜汁| 91粉芽高清在线一区二区| 韩国一级AAA| 国产精品精品系列在线观看| 婷婷午夜清品久久久久久久性色视频观| 蜜桃视频一区二区三区在线观看| 婷婷综合| 99热这里只有精品99| 免费在线黄片视频| 久久天天艹| 成人精品无码| 午夜精品久久久久久久久久久久久| 日本九九久久99| 天天干天天日天天射黄色大片| 99热超碰在线| 久久久久婷婷| 亚洲一区中文字幕一区| 欧美午夜视频精品久久| 日本日逼高清| 亚洲国产婷婷在线播放| av在线播放国产一区| 91在线视频国产网站| 成人情色综合网| 日日噜噜夜夜久久亚洲一区二区 | 欧美真人抽搐一进一出gif| 国产精品天堂| 久久久久亚洲| 麻豆国产97在线| 91亚洲综合| 91无遮挡| 国产精品不卡一区二区电影| 麻豆国产97在线| 无码不卡亚洲成?人片| 大色综合| 亚洲成人精品在线一区| 亚洲无无码αⅴ每日更新| 中国农村熟妇毛片视频| 欧美一级美片在线观看免费| 亚洲欧美在线观看无码| 免费观看国产小粉嫩喷水精品午| 国产精品女久久久久av爽| 国产一区二区三区导航| 久久久夜夜嗨免费视频| 99精品热| 人妻在线中出视频| 天天操人人操骚逼网站| 四虎影视永久在线观看精品免费网站 | 天天操狠狠日夜夜干超大胆开放com大香蕉视频在线观看 | 99∨VTV| 九九热九九热| 美日韩在线不卡人妻| 超碰69| 久久香蕉国产线看观看亚洲女人| 日韩一级二级三级在线不卡观看完整| 亚洲āv网址在线观看| 91青视频| 日韩视频小说在线观看 | 在线精品福利免费播放| a网站免费观看| 日本一区二区电影网站| 亚洲素人网| 新怡红院| 亚洲国产91精品一区二区久久| 国产亚洲精品农村妇女 | 极品美女嘿咻| 亚洲日韩精品久久久久一区壹牛| 亚洲人妻中文高清| 97资源制服丝袜| 亚洲激情色片| 好爽免费视频| 成人三一级一片aaa| 丁香六月天| 97频视在线| 97国产超碰| 日韩一级特黄av毛片| 欧美综合自拍成人自拍第二十页| 青青操少妇| 午夜亚洲| 一区二区影院| 九九久久一区二区三区| 偷窥自拍亚洲| 国产高清免费不卡av| 日韩AV电影网站| 中文日韩欧美熟| J?P?NESEHD熟女熟妇伦| 国产欧美一区激情交| 欧美暴力猛交| 九九热AV| 亚洲人成网www| 啊嗯嗯啊好大好爽| 国产精品 久久久精品一牛| 激情99| 国产中文字幕在线| 操操逼操操逼操操逼逼| 麻豆天美传媒在线视频天堂| 夜夜性| 国产成人精品日本视频| 美骚妇av高清在线| 成人线上超碰| 亚洲 欧美都市激情| 99热欧美| 欧美日韩性爱操大逼| 青青操在线亚洲视频观看欧美在线| 久久在肏| 激情综合五月| 97神马久久| 色情综合| 国产农村妇女毛片精品久久| 精品性爱无码在线播放| 尤物视频偷拍免费| 婷婷激情五月天小说网| 久久一本大香蕉 | 9ⅰ久久久天天| 欧美午夜一区二区三区| 久久久久元码视频| 少妇xx精品| 久久久精品久久| 亚洲αv一区二区三区| 综合网97| 国产精品午夜高潮呻吟久久av| 青青伊人久久| 粉嫩不卡一区二区性爱| 久草久日| 99热婷婷| 成人久久久| 操人妻丝袜高跟| 老熟女乱伦片| 国产精品电影推荐| 亚洲二区精品在线观看| 国产精品97超碰| 日韩精品一区二区三区色欲| 欧美日韩狠狠爱| 天美传媒av 在线| 手机看片91人妻| 安徽熟妇视频| 欧美系列在线一区二区| 大香蕉中文201| 黄页18禁| 成人性爱av.com| 97人人色| 国产精品九9| 日韩美女啪啪一区| 精品制服美女中文一区二区三区| 操人91| 日本成人在线不卡一区二区三区| 情色五月天久久久| 色情乱伦AV| 美女啊啊啊啊啊啊| 自拍二页| 亚洲成人网站在线观看| 12一15性XXXX粉嫩国产| 自拍亚洲综合| 精品一区二区啪啪啪| 中文字幕五月婷婷免费| 1204人成网站色www| 91狠| 欧美日韩性爱无码| 97干97色| 亚洲欧美日韩中文久久自慰| 色蜜AV| 四虎国产精品永久地址入口| 久久久精选| 操B久久| 国产激情久久久| 中文字幕一区二区三区字幕| 欧美草草高清日韩视频| 啊啊好多水| 丁香五月天堂网| 日韩激情啪啪啪| 啊啊啊好舒服视频| 亚洲十八禁止| 日本九九久久99播| 99热伊人| 日韩 欧美 另类 人妻| 蜜臀久久99精品久久久久久婷婷 | 国产宅男宅女在线观看| 999精品久久久久久久| 老司机午夜福利视频一区二区| 大香交伊人网| 色爱三区| 精品欧美А∨无码黑人大荫蒂 | 九九九网页| 综合啪啪| 99热在线观看| 欧美亚洲色图另类国产| 久久狠狠色噜噜狠狠狠狠97| 99超碰网| 欧洲性人爱视频| 试看福利| 久久久久久久久久黄色网| 麻豆天美电影一区二区| 我要看免费韩日黄片| 风流老熟女一区二区三区l| 午夜国产成人精品视频| 老熟女网站| 欧美日韩中文字幕不卡| 婷婷探花久久精品一区| 老司机午夜精品福利视频一区二区| 日韩久久超碰色| 欧美亚洲激情小说| 日本三级韩国三级99| 99爱爱| 日韩av乱伦| 自拍鲍鱼一区在线高清观看免费| 思思性爱| 亚洲偷拍自拍在线视频| 欧亚性爱啪啪| 亚洲色图欧美视频| 日韩在线观看字幕精品| 欧美日韩操操操| 乱欲一区二区| 亚洲第一成人影院色播| 国产精品视频精品一二| 毛片电影一区二区三区| 亚洲精品视频在线播放| 五月丁香啪啪网| 九九成人| 无码欧美有限公司| 黄色高清久久无码依人| 91天美传媒在线| 久久夜精品一区二区三区| 精品人妻无码一区二区三区不卡-精品人妻无码一区二区...|精品少妇一区二区三 | 亚洲一区二区性爱电影| 人人操人人大香蕉| 婷婷久久五月| 久草成人福利导航| 少妇六月天| 蜜臀久久99精品| 伊人视频| 久久色精品视频在线| 人人么人人操| 四虎影视永久在线免费| 99精品成人免费看| 夜色五月天| 亚州色站 日韩电影| 欧美日韩亚洲五月天婷婷| 超碰这里有精品| 外国免费性情大片| 一级毛片电影免费看| 99久久久无码精品国产人| 久久精视频美日韩在线视频| 国产亚洲99久久精品| 日本三级人妻a人妻一在线| 超碰综合色| 日韩精品人妻中文字幕不卡乱码| 欧美中文综合| 国产一区二区三区免费视频在性观看| 国产综合网站在线播放 | 男人干美女| 99精品在线| 国产福利精品98视频| 亚洲无吗在线视频| 午夜免费视频1000| 淫乱图区| 亚洲一区二区AV| 国产精品无码久久久久2028| 五月激情小说| 亚洲熟久久| 五月天亚洲色图| 久久久精品无码亚免费| 九九热免费国产视频婷婷伊人五月 | 精品久久久久综合无码| 色翁荡息又大又硬又粗又爽| 九九热精品| 91久久久久久久| 亚洲网站一区二区在线| 粉嫩在线一区二区懂色| 欧美一级欧美三级在线观看| 亚洲熟女乱综合一区二区在线-...亚洲国产日韩欧美一区二区三区,久久久久久精 | 亚洲色欲一区二区三区| 97国产伦理| 一起草高清无码| 日韩免费性爱视频在线观看| 久久久久9999妇女| 91欧美亚洲| 思思热免费视频观看| 91jk色拍| 97在线观看| 二色av| 亚洲精品不卡一二三区| 日韩性爱啪啪视频| www.天天干| 青草伊人久久| japan日本高清乱xxxx| 热天堂一区二区| 992视频一区| 中文字幕在线观看二区三区| 农村妇女精品一区二区| 100啪啪视频大全| 亚殴在线| 麻豆美女丝袜人妻中文| 色婷婷影院| 床戏久久久av一区二区麻豆| hd成人一区二区在线| 99色骚| 日韩熟女乱伦中出| 好看的91视频| 无码精品久久| 一区二区 日韩 欧美 国产 传媒| 超碰97久久| 97九色人妻| 丰满人妻区一区二区三| 女人的久久久| 日日骚AV| 任我爽视频在线观看| 欧美日韩中文视频播放| 国产精品久久久亚洲一区| 欧美情色亚洲| 99色视频| 91狠狠综合| 日日AV加勒比| 神马久久久久久伦理片| 大乔未久88一区| 九色在线熟女国产黑人| 97天天插| 久久九九网| 麻豆精品.欧美精品.日韩精品.| 色婷婷丁香五月| 91天天综合日韩欧美| 97精品国产97久久久| 国产高清自拍| 久插不卡| 自拍偷拍 日韩无码| 日韩精品人妻中文字幕不卡乱码| 亚洲精品视频在线播放| 中文字幕在线免费观看| 青青操97| 日韩操逼HD| 少妇精品久久久八区九区| 亚洲精品成人| 久久男人的天堂| 久久夜嗨| AV无码久久久精品| 日韩精品 欧美激情| 久久久久久性爱片| 欧美另类精品xxxx| 日本二区不卡| 日本天天人人狠狠在线日美女 | 亚洲国产欧美中文永久| 精品人妻无码一区二区三区不卡-精品人妻无码一区二区...|精品少妇一区二区三 | 91久久午夜无码鲁丝片久久人妻| 日本乱人伦片中文三区| 欧美熟妇亚洲版| 日本岛国黄色网址| 久久精品国产亚洲5555| 日韩精品大香蕉伊人在线| www.色婷婷色综合| 欧美Ⅴ性爱| 久欲AV| 美女黄页| 亚洲一区二区三区四区视频| 天天射日日干| 日日骚精品视频| 蜜臀久久99精品久久久久久久久| 91精品久久久| 色九久| 天堂资源站| 精品区9| 亚洲欧美在线观看2021 | 欧美另类色| 自拍偷拍 日韩无码| 亚洲无线观看久久| 中日992视频| 日日夜夜国产综合| 欧美综合自拍成人自拍第二十页| 大学生口爆吞精| 91 丝袜在线播放| 青青操视频在线| 亚洲AV资源| 先锋精品av色鲁| 亚洲情色中文字幕一区| 青青青国产手线观看视频2| 婷婷久久久精品| 夜精品久无码| 啊啊啊啊啊操我视频| 丁香五月激情啪啪| 亚洲情色中文字幕一区| 一个色导综合| 日日夜夜摸| 天天天干977| 久草久日| 亚洲日韩熟女人妻高清在线| 九九九久千久久激情蜜桃在线看 | 欧美日韩性爱电影在线| 9999久久久| 97视频播放| 青女偷拍网| WWW美腿丝袜香蕉中文| 四虎视频在线观看| 宅男午夜在线视频| 天天日B狠狠操| AA丁香综合激情| 精品国产精品一区二区| 天天干天天操天天干天天操| 国产精品女生av| 日韩黄色片子| 久久久精品中文字幕爱豆| 日韩免费a级毛片无码a∨| 天天综合网在线观看| 日韩九九九| 亚洲欧美综合图片| 天天夜夜rb| 久久久偷拍| 超碰美国| 91啪啪| A级国产欧美激情在线| 超碰97久久| 亚洲中字幕日本一区二区三区| 天天噜| 亚洲色婷婷久久91| AV麻豆免费一区| 综合av社区| 国产精品嫩草久久久久| 懂色av色欲av蜜臀av| 日韩精品1区2区中文字幕| 久草视频在线视频在线视频在线观看| 亚洲天堂中文字| 一区二区三区免费岛国片| 国产美女mm131爽爽爽爽| 91精品人妻电影| 啊视频在线| 亚洲 欧美 91| 色婷婷综合久久久久中文一区二区| 亚洲综合影片| 青青草字幕AV| 亚洲脚交| 九九九九久久久久| 久久精品国产欧美日韩亚洲欧美日韩中文久久国产一区 | 91色人| 粉嫩av一区二区三区天美传媒 | 亚洲 欧美都市激情| 热天堂一区二区| 久久久久密臀视频| 舔人妻中文免费视频| 美女91| 香蕉黄色一级视频| 26uuu国产免费观看| 屌色在线97视频| 亚洲欧美另类少妇精品| 操淫穴亚洲五月丁香| 97久久久久| 1769国内精品视频| 国产亚州日韩欧美看片| 久久久久日本视| 日韩精品9区| 亚洲色婷婷综合久久久久中文| 97视频免费在线观看| 午夜视频好爽啊| 狠狠干婷婷| 欧美高潮在线| 超碰97人妻自拍| 性色av大全| 中文字幕成人| 刺激精品视频| 青青草大香蕉视频| 日韩无码精品综合久久| 中文字幕在线高清男人的天堂| 人妻密肉在线观看| 97超碰欧美手机在线| 在线视频免费观看午夜| 午夜欧美女人操逼| 99999精品成人| 五月天精品| 老熟女乱伦一区| 丁香五月激情综合| 9 9无尺码天堂网| A 天堂| 大香蕉啪啪啪| 97超碰人操| 免费A片三p视频| 天天色播| 91美女视频在线免费观看| 大香蕉综合网| 日本韩欧美在线播放a| 97在线欧洲| 78久久| 亚洲欧美成人在线| 好爽免费视频,| 亚洲高清无毛一区二区| 夜夜嗨一区二区| 亚洲激情深爱文学小说网站| 人人操我人人干| 久久久9视频| 午夜传煤十二区精品| 成人免费福利网站国产| 超碰中文字幕人妻草一区| 91 欧美| 色色色热| 97中文字幕一区| 婷婷丁香五月天亚洲天堂网| 九九成人精品| 国产 日韩 欧美一区| 920日本午夜免费| 性感美女91影视| 国产精品亚洲免费| 欧美日日人人天天| 青娱乐国产盛宴视频| 久久 亚洲 日韩 人妻| 人人模人人看| 亚洲另类久操网| 欧美色女人| 日韩性色b| 亚洲色狠| 狼人综合婷婷激情四射| 91精片| 国产四虎在线| 日韩综合无码一区久久92| 国产馆极品诱惑| 伊人天天久久动态图| 日本有码影片下载| 加勒比海色香蕉婷婷| 91在线欧色| 欧美亚洲| 色综合潮| 欧美日韩色综合网| 亚洲一区二区 麻豆传媒| 亚洲字幕一区二区| 日本精品久久久久久久| 日操粉逼逼| 天天性射网| 国产又粗又又黄又猛| 人人妻人人玩人人澡人人爽| 97干日韩| 久久透逼视频| 国产精品久久久久久久久久久久久久久久 | 色丁香五月婷婷| 蜜臀AV一区二区三区| 黄污污污污| 久久久久久久强迫| 久久 亚洲 日韩 人妻| 久久直播国产| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲综合色婷婷| 精品午夜福利导航| 污污污8888| 在线观看黄色电话| 大奶的诱惑| 黄总AV色图| 狠狠色噜噜狠狠狠狠狠色综合久久| 热热色青青草| 色av中文字| 国产精品视频麻豆入口| 久久久天堂| 中文字幕一二三区| 国产AV久久野战精品| 久久在肏| 一区二区不卡| 激情色播| 中文字幕一区二区免费在线| julia ann久久| 久久秀这里有精品| 逼操网站| 亚洲欧美黄| 亚洲色图 图片| 亚洲男人bt天堂| 色在线亚洲视频www| 懂色Av一区二区三区| 亚洲中文电影| 婷婷大香蕉| 欧美天天干| 欧美日韩在线小说| 国产成人天堂| 欧美三级不卡| 丁香五月综合| TS人妖另类精品视频系列| 精品9999| 亚州乱码中文字幕综合久久久| 日本理论在线| 在线岛国新天堂8| 欧美性91| 二级毛片| 在线观看A啊啊啊| 九九内射在线| 天天色综亚洲91污| 性饥渴少妇av无码毛片| 中文字幕成人乱码熟女精品国50| 91久久国产综合精品| 国产熟女少妇一区| 大伊香蕉在线视频免费| 欧美精品久久久久久久丰满| 肥臀熟女一区二区三区视频| 老熟女中文字幕高清| 伊人久久大香大香线蕉中文| 欧美刺激色黄片免费看| 国产黄色剧情影片麻豆免费播放| 欧美日韩亚洲电影| 欧美天天综| 人妻天堂综合网| 人人妻人人狠人人| 国产精品亚洲一级av第二区| 天美91| 女生看匆91网站| 91亚.色| 少妇精品久久久| 又摸又舔在线观看网站| 91九久| 亚洲精品男人的天堂| 极品极品色影院| 亚洲乱码国产乱码精网站| 91午夜无码| 国产精品嫩草影院午夜两性| 日韩欧美加勒比| 超清中文乱码字幕| 亚洲欧美黄| 五月情色天| 欧美亚洲首页| 97超碰精品图片| 日日夜夜骑| 国产精品久久久久9999小说| 国产国产亚洲一二三久久| 久久网亚洲| 91高清日| 亚州欧美在线| 97久久久久| 欧美丝袜中文字幕07在线| 青女偷拍网| 加勒比海人人操超碰在线| 久久久91| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 亚州 综合 色图| AV丝袜少妇| 好舒服视频| 好吊爽好吊爽在线视频,中文字幕精品一区二区日本,国产良妇出轨视频在线观看, | 91深夜夜| 亚洲一区二区三区不卡国产欧美| 久久欲| 国产精品一区午夜福利| 口爆吞精在线观看| 国产女性无套 免费观看| 一区二区娱乐网站| 91neishe| 色九九九九| 日韩中文字幕精品一二三事国产精品|