+ /**
+ * generate a regex fragment out of a tag
+ * @param string $tag to to generate regexs from. may start with '-' to negate, contain '*' as wildcard
+ * @return string generated regex fragment
+ */
+ private static function tag2regex($tag)
+ {
+ $len = strlen($tag);
+ if(!$len || $tag === "-" || $tag === "*"){
+ // nothing to search, return empty regex
+ return '';
+ }
+ if($tag[0] === "-") {
+ // query is negated
+ $i = 1; // use offset to start after '-' character
+ $regex = '(?!'; // create negative lookahead
+ } else {
+ $i = 0; // start at first character
+ $regex = '(?='; // use positive lookahead
+ }
+ $regex .= '.*(?:^| )'; // before tag may only be a space or the beginning
+ // iterate over string, separating it into placeholder and content
+ for(; $i < $len; $i++){
+ if($tag[$i] === '*'){
+ // placeholder found
+ $regex .= '[^ ]*?';
+ } else {
+ // regular characters
+ $offset = strpos($tag, '*', $i);
+ if($offset === false){
+ // no placeholder found, set offset to end of string
+ $offset = $len;
+ }
+ // subtract one, as we want to get before the placeholder or end of string
+ $offset -= 1;
+ // we got a tag name that we want to search for. escape any regex characters to prevent conflicts.
+ $regex .= preg_quote(substr($tag, $i, $offset - $i + 1), '/');
+ // move $i on
+ $i = $offset;
+ }
+ }
+ $regex .= '(?:$| ))'; // after the tag may only be a space or the end
+ return $regex;
+ }
+