mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-27 03:57:21 +00:00
implemented the new regexp syntax
This commit is contained in:
parent
81de74342d
commit
14ca91a949
@ -32,55 +32,57 @@ function parseFilterOperation(operators,filterString,p) {
|
||||
if(filterString.charAt(p) === "!") {
|
||||
operator.prefix = filterString.charAt(p++);
|
||||
}
|
||||
|
||||
// Get the operator name
|
||||
bracketPos = filterString.indexOf("[",p);
|
||||
curlyBracketPos = filterString.indexOf("{",p);
|
||||
if((bracketPos === -1) && (curlyBracketPos === -1)) {
|
||||
var nextBracketPos = filterString.substring(p).search(/[\[\{\/]/);
|
||||
if(nextBracketPos === -1) {
|
||||
throw "Missing [ in filter expression";
|
||||
}
|
||||
if(bracketPos === -1 || (curlyBracketPos !== -1 && curlyBracketPos < bracketPos)) {
|
||||
// Curly brackets
|
||||
operator.indirect = true;
|
||||
operator.operator = filterString.substring(p,curlyBracketPos);
|
||||
p = curlyBracketPos + 1;
|
||||
} else {
|
||||
// Square brackets
|
||||
operator.operator = filterString.substring(p,bracketPos);
|
||||
p = bracketPos + 1;
|
||||
}
|
||||
nextBracketPos += p;
|
||||
var bracket = filterString.charAt(nextBracketPos);
|
||||
operator.operator = filterString.substring(p,nextBracketPos);
|
||||
|
||||
// Any suffix?
|
||||
var colon = operator.operator.indexOf(':');
|
||||
if(colon > -1) {
|
||||
operator.field = operator.operator.substring(colon+1);
|
||||
operator.operator = operator.operator.substring(0,colon);
|
||||
operator.operator = operator.operator.substring(0,colon) || "field";
|
||||
}
|
||||
if(operator.operator === "") {
|
||||
// Empty operator means: title
|
||||
else if(operator.operator === "") {
|
||||
operator.operator = "title";
|
||||
}
|
||||
var rexMatch;
|
||||
// regexp?
|
||||
if(!operator.indirect && filterString.charAt(p) === "/") {
|
||||
var rex = /^\/((?:[^\\\/]*|\\.))*\/([igm]*)\]/g;
|
||||
rexMatch = rex.exec(filterString.substring(p));
|
||||
|
||||
p = nextBracketPos + 1;
|
||||
switch (bracket) {
|
||||
case '{': // Curly brackets
|
||||
operator.indirect = true;
|
||||
nextBracketPos = filterString.indexOf('}',p);
|
||||
break;
|
||||
case '[': // Square brackets
|
||||
nextBracketPos = filterString.indexOf(']',p);
|
||||
break;
|
||||
case '/': // regexp brackets
|
||||
var rex = /^((?:[^\\\/]*|\\.))*\/(?:\(([mygi]+)\))?/g,
|
||||
rexMatch = rex.exec(filterString.substring(p));
|
||||
if(rexMatch) {
|
||||
try {
|
||||
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
|
||||
}
|
||||
catch(e) {
|
||||
// an error in the regexp -> Will do string matching
|
||||
}
|
||||
operator.operand = filterString.substr(p,rex.lastIndex-1);
|
||||
p += rex.lastIndex;
|
||||
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
|
||||
nextBracketPos = p + rex.lastIndex - 1;
|
||||
}
|
||||
}
|
||||
// Get the operand
|
||||
if(!rexMatch) {
|
||||
bracketPos = filterString.indexOf(operator.indirect ? "}" : "]",p);
|
||||
if(bracketPos === -1) {
|
||||
throw "Missing closing bracket in filter expression";
|
||||
else {
|
||||
throw "Unterminated regular expression in filter expression";
|
||||
}
|
||||
operator.operand = filterString.substring(p,bracketPos);
|
||||
p = bracketPos + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(nextBracketPos === -1) {
|
||||
throw "Missing closing bracket in filter expression";
|
||||
}
|
||||
if(!operator.regexp) {
|
||||
operator.operand = filterString.substring(p,nextBracketPos);
|
||||
}
|
||||
p = nextBracketPos + 1;
|
||||
|
||||
// Push this operator
|
||||
operators.push(operator);
|
||||
} while(filterString.charAt(p) !== "]");
|
||||
|
@ -44,7 +44,8 @@ A filter string consists of one or more runs of filter operators that each look
|
||||
* ''prefix'': tests whether a tiddlers title starts with the prefix specified in the operand
|
||||
* ''limit'': limits the number of subresults to the integer specified in the operand
|
||||
* ''tag'': tests whether a given tag is (`[tag[mytag]]`) or is not (`[!tag[mytag]]`) present on the tiddler
|
||||
* ''{field}'': tests whether a tiddler field has a specified value (`[modifier[Jeremy]]`) or not (`[!modifier[Jeremy]]`)
|
||||
* ''field:{field}'': or
|
||||
* ''{field}'': tests whether a tiddler field has a specified value (`[modifier[Jeremy]]` or `[field:modifier[Jeremy]]`) or not (`[!modifier[Jeremy]]`)
|
||||
* ''tags'': selects the tags on the currently selected tiddlers
|
||||
* ''tagging'': selects the tiddlers tagged with the currently selected tiddlers
|
||||
* ''untagged'': selects the any of the selected tiddlers that do not have at least one tag
|
||||
@ -79,6 +80,16 @@ If a filter operator is written with curly brackets around the operand then it i
|
||||
|
||||
''[search{$:/temp/search}]'': selects all tiddlers containing the string contained in the tiddler titled ''$:/temp/search''.
|
||||
|
||||
! Regular Expression Filters
|
||||
|
||||
The field-filter also accepts regular expressions in the form `/regexp/(modifier)`. Please refer to you favourite JavaScript documentation to learn more about regular expressions and modifiers.
|
||||
|
||||
In the easiest form, regular expressions allow you do do a search on substrings for every field:
|
||||
|
||||
* `field:title/example/`: searches for all tiddlers having "example" in its title.
|
||||
* `field:title:/example$/`: `$` is an "anchor" for the end of the text. So "example" has to be the end of the title.
|
||||
* `field:text/jeremy|ruston/(i)`: Searches for tiddlers containing Jeremy's first or last name, ignoring the case.
|
||||
|
||||
! Runs
|
||||
|
||||
Operators are combined into runs that function as logically ANDed expressions by bashing them together and merging the square brackets:
|
||||
|
Loading…
Reference in New Issue
Block a user