UNPKG

1.4 kBJavaScriptView Raw
1/**
2 * @param {string | RegExp} a
3 * @param {string | RegExp} b
4 * @param {string} str
5 */
6export default function balanced (a, b, str) {
7 if (a instanceof RegExp) a = maybeMatch(a, str)
8 if (b instanceof RegExp) b = maybeMatch(b, str)
9
10 const r = range(a, b, str)
11
12 return (
13 r && {
14 start: r[0],
15 end: r[1],
16 pre: str.slice(0, r[0]),
17 body: str.slice(r[0] + a.length, r[1]),
18 post: str.slice(r[1] + b.length)
19 }
20 )
21}
22
23/**
24 * @param {RegExp} reg
25 * @param {string} str
26 */
27function maybeMatch (reg, str) {
28 const m = str.match(reg)
29 return m ? m[0] : null
30}
31
32/**
33 * @param {string} a
34 * @param {string} b
35 * @param {string} str
36 */
37export function range (a, b, str) {
38 let begs, beg, left, right, result
39 let ai = str.indexOf(a)
40 let bi = str.indexOf(b, ai + 1)
41 let i = ai
42
43 if (ai >= 0 && bi > 0) {
44 if (a === b) {
45 return [ai, bi]
46 }
47 begs = []
48 left = str.length
49
50 while (i >= 0 && !result) {
51 if (i === ai) {
52 begs.push(i)
53 ai = str.indexOf(a, i + 1)
54 } else if (begs.length === 1) {
55 result = [begs.pop(), bi]
56 } else {
57 beg = begs.pop()
58 if (beg < left) {
59 left = beg
60 right = bi
61 }
62
63 bi = str.indexOf(b, i + 1)
64 }
65
66 i = ai < bi && ai >= 0 ? ai : bi
67 }
68
69 if (begs.length) {
70 result = [left, right]
71 }
72 }
73
74 return result
75}