예제 #1
0
파일: trex.go 프로젝트: chengguozhen/clive
func replre(s string, re *sre.ReProg, to string, glob bool) string {
	rfrom := []rune(s)
	rto := []rune(to)
	nrefs := 0
	for i := 0; i < len(rto)-1; i++ {
		if nb := rto[i+1]; rto[i] == '\\' {
			if nb >= '0' && nb <= '9' {
				nb -= '0'
				rto[i] = nb
				nrefs++
				n := copy(rto[i+1:], rto[i+2:])
				rto = rto[:i+1+n]
			} else if nb == '\\' {
				n := copy(rto[i+1:], rto[i+2:])
				rto = rto[:i+1+n]
			}
		}
	}
	st := 0
	for {
		cmd.Dprintf("re match [%d:%d]\n", st, len(rfrom))
		rg := re.ExecRunes(rfrom, st, len(rfrom))
		if len(rg) == 0 {
			break
		}
		r0 := rg[0]
		var ns []rune
		ns = append(ns, rfrom[:r0.P0]...)
		if nrefs == 0 {
			ns = append(ns, rto...)
		} else {
			for _, r := range rto {
				if r > 10 {
					ns = append(ns, r)
					continue
				}
				if r < rune(len(rg)) {
					t := rfrom[rg[r].P0:rg[r].P1]
					ns = append(ns, t...)
				}
			}
		}
		st = len(ns)
		ns = append(ns, rfrom[r0.P1:]...)
		rfrom = ns
		if !glob {
			break
		}
	}
	return string(rfrom)
}
예제 #2
0
func cmdXY(s *Sam, c *Cmd) {
	if s.inXY {
		panic("can't next X or Y commands")
	}
	s.inXY = true
	defer func() { s.inXY = false }()

	var re *sre.ReProg
	var err error
	if c.Rexp != nil {
		if re, err = sre.Compile(c.Rexp, sre.Fwd); err != nil {
			panic(fmt.Sprintf("%c: regexp: %s", c.Ch, err))
		}
	} else if c.Ch == 'Y' {
		panic("Y: no regexp given")
	}
	nf := make([]*file, len(s.f))
	copy(nf, s.f)
	for _, f := range nf {
		matches := true
		if re != nil {
			nm := f.MenuLine() + "\n"
			rg := re.ExecStr(nm, 0, len(nm))
			matches = len(rg) > 0
		}
		if (c.Ch == 'X' && !matches) || (c.Ch == 'Y' && matches) {
			continue
		}
		c.dot = f.Sel()
		for _, child := range c.Child {
			child.dot = c.dot
			if err := s.runCmd(child); err != nil {
				s.Out <- fmt.Sprintf("%s\n", err)
			}
		}
	}
}