新手问题 咨询一个正则表达的小问题

luffycn · 2015年01月30日 · 最后由 alixiaomiao 回复于 2015年01月30日 · 1647 次阅读

[hi1]content1[hi2]content2[h3]content3

如果想截取 [hi1] [h2] [h3] 之间的文本内容 要怎么写了

\]([^\]]+?)\[

效果

非贪婪模式即可 str.scan(/](.*?)[/)

@leopku thanks. 顺便请教下,为何这个规则行不通 /\[.\](.)\[.\]/ 我的想法是,前后各一个括号,中间用 (.) 这个思路主要是哪错了

#3 楼 @luffycn 我来说一下你这个正则的大概工作流程。

  1. 首先 \[ 开始匹配,第一个正好匹配
  2. 接着匹配 .*,这个贪婪匹配会吞所有的字符,从 h 开始吞到最后一个字符 3,之后没得吞了,这部分匹配结束,这时候 .* 匹配的是 hi1]content1[hi2]content2[h3]content3。虽然 .* 吞了所有字符,但是在每个字符的地方都保留了一个可选状态。
  3. 接着匹配 \],没得匹配,因此控制权返回到 .*.* 为了大局观,只好不情愿的让出一个字符 3,这时 \]3 依然不匹配。控制权再次返回到 .*.* 只好又让出一个字符 t,但是还不匹配,.* 只好继续让出字符,直到让出第一个 ],此时匹配了。
  4. 接着匹配捕获组 (.*),这个结构同理会吞掉 content3
  5. 接着匹配 \[,这是不匹配的,因此控制权返回 (.*)(.*) 也只能让出一个字符 3,同第 3 步,但是这里 (.*) 让出了所有的字符, \[ 依然不能匹配。
  6. 此时控制权只能继续往前,交给第一个 .*.* 只好继续让出字符,直到第一个 .* 匹配了 hi1]content1[hi2,然后控制权交给其后的 \],这时正好能匹配。
  7. 之后 (.*) 继续吞掉 ]content2[h3]content3,吞完之后控制权交给其后的 \[
  8. 但是这又不匹配了,(.*) 只好让出 3,但是 \[ 依然不匹配 3(.*) 只好继续让出字符,直到让出第一个 [,这时 (.*) 捕获的内容是 content2
  9. 接着匹配 \[ 之后的 .*,这个结构继续吞掉 h3]content3,然后匹配 \],依然不匹配。
  10. 于是 .* 只好挨个又让出 t n e 直到让出 3,然后 \] 匹配 h3] 里面的那个 ],这个 .* 匹配了 h3

整个匹配结束时,第一个 .* 匹配了 hi1]content1[hi2,第二个 .* 匹配了 content2,第三个 .* 匹配了 h3

需要 登录 后方可回复, 如果你还没有账号请 注册新账号