github.com/cayleygraph/cayley@v0.7.7/graph/iterator/regex.go (about) 1 // Copyright 2014 The Cayley Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package iterator 16 17 import ( 18 "regexp" 19 20 "github.com/cayleygraph/cayley/graph" 21 "github.com/cayleygraph/quad" 22 ) 23 24 func newRegex(qs graph.Namer, sub graph.Iterator, re *regexp.Regexp, refs bool) graph.Iterator { 25 return NewValueFilter(qs, sub, func(v quad.Value) (bool, error) { 26 switch v := v.(type) { 27 case quad.String: 28 return re.MatchString(string(v)), nil 29 case quad.LangString: 30 return re.MatchString(string(v.Value)), nil 31 case quad.TypedString: 32 return re.MatchString(string(v.Value)), nil 33 default: 34 if refs { 35 switch v := v.(type) { 36 case quad.BNode: 37 return re.MatchString(string(v)), nil 38 case quad.IRI: 39 return re.MatchString(string(v)), nil 40 } 41 } 42 } 43 return false, nil 44 }) 45 } 46 47 // NewRegex returns an unary operator -- a filter across the values in the relevant 48 // subiterator. It works similarly to gremlin's filter{it.matches('exp')}, 49 // reducing the iterator set to values whose string representation passes a 50 // regular expression test. 51 func NewRegex(sub graph.Iterator, re *regexp.Regexp, qs graph.Namer) graph.Iterator { 52 return newRegex(qs, sub, re, false) 53 } 54 55 // NewRegexWithRefs is like NewRegex but allows regexp iterator to match IRIs and BNodes. 56 // 57 // Consider using it carefully. In most cases it's better to reconsider 58 // your graph structure instead of relying on slow unoptimizable regexp. 59 // 60 // An example of incorrect usage is to match IRIs: 61 // <http://example.org/page> 62 // <http://example.org/page/foo> 63 // Via regexp like: 64 // http://example.org/page.* 65 // 66 // The right way is to explicitly link graph nodes and query them by this relation: 67 // <http://example.org/page/foo> <type> <http://example.org/page> 68 func NewRegexWithRefs(sub graph.Iterator, re *regexp.Regexp, qs graph.Namer) graph.Iterator { 69 return newRegex(qs, sub, re, true) 70 }