示例#1
0
func Test_Is_In_Strings(t *testing.T) {
	bs := []string{"abc", "bcd", "cde", "efg"}
	if !z.IsInStrings(bs, "bcd") {
		t.Error("bcd should be 1")
	}
	if z.IsInStrings(bs, "z123") {
		t.Error("z123 should be -1")
	}
}
示例#2
0
// 解析查询字符串
func (qb *QWBuilder) Parse(kwd string) *QWord {
	kwd = z.TrimExtraSpace(kwd)
	if len(kwd) == 0 {
		return nil
	}
	isGOr, isGAnd, flds, seps := qb.extractFldsAndSeps(kwd)
	// 解析为QWord
	qword := new(QWord)
	qword.CndMap = map[string]*QCnd{}
	sseps := len(seps)
	for i, fld := range flds {
		// qcnd
		qc := qb.evalQCnd(fld)
		if qc != nil {
			qword.Cnds = append(qword.Cnds, qc)
			qword.CndMap[qc.Key] = qc
			// 分隔符
			if i < sseps {
				sp := "&"
				if isGOr {
					sp = "|"
				} else if isGAnd {
					sp = "&"
				} else if z.IsInStrings(qb.SepOr, string(seps[i])) {
					sp = "|"
				} else if z.IsInStrings(qb.SepAnd, string(seps[i])) {
					sp = "&"
				}
				qword.Rels = append(qword.Rels, sp)
			}
		} else {
			qword.Unmatchs = append(qword.Unmatchs, fld)
		}
	}
	return qword
}
示例#3
0
// 提取查询语句与连接符
func (qb *QWBuilder) extractFldsAndSeps(kwd string) (isGOr, isGAnd bool, flds []string, seps []byte) {
	// 判断全局参数 (先强制认为 'xxx:')
	// FIXME 后面改成正则匹配, 可以多加空格
	isGOr = strings.HasPrefix(kwd, qb.GOr+":")
	isGAnd = strings.HasPrefix(kwd, qb.GAnd+":")
	if isGOr || isGAnd {
		kwd = kwd[strings.Index(kwd, ":")+1:]
	}
	// 分割查询字符串
	flds = make([]string, 0, 5)
	seps = make([]byte, 0, 5)
	// FIXME 这个地方需要在好好想想
	// 保证一个特殊情况下的正确性, 比如或是" "与是"," kwd中有类似"xxx , yyy"这样的语句,需要把处理
	// 这个特例是一搬在" "当做或的情况下
	if z.IsInStrings(qb.SepOr, " ") {
		for _, sAnd := range qb.SepAnd {
			ss := " " + sAnd + " "
			kwd = strings.Replace(kwd, ss, sAnd, -1)
		}
	}
	// 开始解析
	kszie := len(kwd)
	fld := z.StringBuilder()
	for i := 0; i < kszie; i++ {
		c := kwd[i]
		z.DebugPrintf("extract kwd %3d -> [%s]\n", i, string(c))
		// 如果是引用
		if pos := z.IndexOfStrings(qb.QuoteBegin, string(c)); pos > 0 {
			// 这里面的空格啥的就不会被跳过了, 会一直取到引用结束, 逃逸字符会调整一下
			for i++; i < kszie; i++ {
				c = kwd[i]
				if string(c) == qb.QuoteEnd[pos] {
					break
				} else if c == '\\' {
					// FIXME 这里没有做防守
					i++
					fld.Append(kwd[i])
				} else {
					fld.Append(c)
				}
			}
			continue
		}
		// 如果是括弧
		if z.IsInStrings(qb.BracketBegin, string(c)) {
			fld.Append(c)
			for i++; i < kszie; i++ {
				c = kwd[i]
				fld.Append(c)
				if z.IsInStrings(qb.BracketEnd, string(c)) {
					break
				}
			}
			continue
		}
		// 如果是分隔符
		if z.IsInStrings(qb.SepAnd, string(c)) || z.IsInStrings(qb.SepOr, string(c)) {
			cfld := z.Trim(fld.String())
			if len(cfld) > 0 {
				flds = append(flds, cfld)
				seps = append(seps, c)
				fld = z.StringBuilder()
			}
			continue
		}
		// 没什么特殊情况,那就加入到sb
		fld.Append(c)
	}
	// 加入最后一个条件
	lfld := z.Trim(fld.String())
	if len(lfld) > 0 {
		flds = append(flds, lfld)
	}
	// 打印一下
	if z.IsDebugOn() && len(flds) > 0 {
		z.DebugPrintf("kwd : %s\n", kwd)
		for _, f := range flds {
			z.DebugPrintf("fld : %s\n", f)
		}
		for _, s := range seps {
			z.DebugPrintf("sep : '%s'\n", string(s))
		}
	}
	return isGOr, isGAnd, flds, seps
}