Regexp for matching a tag? (@TiddlyTweeter)

271 views
Skip to first unread message

Mat

unread,
Aug 8, 2018, 6:31:00 AM8/8/18
to TiddlyWiki
What is the regexp for matching a tag in the tags field. Should bea basic use case... but I just don't nail it. 

(The @TiddlyTweeter is because I recall Josiah a.k.a TiddlyTweeter has mentioned he's good at regexps but I of course welcome help from anyone.)

So, for the tag "Foo", the regexp should trigger on all of the following tags field values (i.e each row is a separate tags field)

Foo Bar Baz

Bar Foo Baz

Bar Baz Foo

[[Foo]] Bar Baz


I.e Foo may or may not be surrounded by space characters - or by double brackets on both sides.

But it should not trigger when Foo is surrounded by other characters, or merely double brackets on one side, for example:

NotFoo Bar Baz

Not [[Foo Bar]]

Not [[Foo


...unless, of course, the searched for pattern does have one or several space characters in it, in which case the double brackets are required. E.g for Foo Foo this is OK:

Bar [[Foo Foo]] Baz

...but the following is not because the seached for string had a space in it which implies there must also be brackets around it 

Bar Foo Foo Baz


Thank you!


<:-)

Mark S.

unread,
Aug 9, 2018, 2:32:19 PM8/9/18
to TiddlyWiki
Hi Mat,

You seem to want to look at something like "[[Foo]] Bar Baz" as a whole string. I'm not sure how to even set that up experimentally, because TW constantly wants to turn it into a title list, with each item viewed as a title. As far as a regular expression that just finds "Foo" (assuming a standard title list) then regexp[^Foo$] should work.

-- Mark

Mat

unread,
Aug 9, 2018, 4:14:27 PM8/9/18
to TiddlyWiki
Thanks for reply, Mark!

You seem to want to look at something like "[[Foo]] Bar Baz" as a whole string. I'm not sure how to even set that up experimentally, because TW constantly wants to turn it into a title list, with each item viewed as a title.

I'd think all the cases where you're forced to use the enlist filter operator would mean that if you don't use it, then the arg is seen as one string. No?
 
But, regardless, doesn't the regexp:field[] filter op always interpret any field content as one string because regexp:tags[oo ba] would show positive for the tags "foo bar". I.e AFAICT, the space character is just a character to regexp, not a separator. 



As far as a regular expression that just finds "Foo" (assuming a standard title list) then regexp[^Foo$] should work.

If there is anything more in the field, such as is common the tags field, then that syntax would give a false negative.

The actual use case for my question is the toggle-in-field plugin. I have thus far used regexp[\b$item$\b] like so 

<$list filter="[[$tiddler$]has[$field$]regexp:$field$[\b$item$\b]]">

This is actually pretty good but it gives a false positive in a TW context(!) where a title Foo must not be confused with a title [[Foo bar]]. There needs to be some condition that a prefixing [[ also requires a suffixing ]] but I'm not sure how to deal with bracket characters in a filter and if it is at all possible.

Thanks for your input, Mark!

<:-)

Diego Mesa

unread,
Aug 9, 2018, 4:23:40 PM8/9/18
to TiddlyWiki
Hey Mat,

Just wanted to bring to your attention Tobias' excellent split plugin:


which might be of interest!

Mark S.

unread,
Aug 9, 2018, 7:09:58 PM8/9/18
to TiddlyWiki
Ok, something to try:

\define removeme() [[$(item2)$]]
\define empty()
<$vars appendme="[[$(item2)$]]">
 
<$button class="tc-btn-invisible">
     
<$action-listops $tiddler='$(tiddler)$' $field="$(field)$"
           $subfilter
="+[append<appendme>]"/>
     
{{$:/image/checkbox1}} <<label>>
   
</$button>
<$vars>
\end
\define toggle-in-field(tiddler, field, item, item2, label)
<$set name=item2 value='$item2$' emptyValue='$item$'>
<$set name=label value='$label$' emptyValue='[[$item$]]'>
<$vars tiddler="""$tiddler$""" field="""$field$""">
<div style="white-space:nowrap; display:inline-block; margin-right:3px;">
<$list filter="[enlist{$tiddler$!!$field$}regexp[^$item$$]limit[1]]" variable=n1 emptyMessage=<<empty>>>
   <$button class="tc-btn-invisible" >
      <$action-listops $tiddler='$tiddler$' $field="$field$"
         $subfilter="+[remove<removeme>]"/
>
     
{{$:/image/checkbox2}} <<label>>
   
</$button>
</
$list>
</div>
</
$vars>
</$set>
</
$set>
\end

It seems to work with your Foo bar examples, but my testing was pretty brief. It does NOT use variable #2, because I don't understand yet what you want to do with that. Perhaps you could explain in more detail.

There was some TW-Logic errors (TW-Logic is not to be confused with the real thing). This line presents problems:

   <$set name=item2 value='$item2$' emptyValue='[[$item$]]'>

Because if there is a value then the rest of the code sees a simple text string, but if there is not a value than the rest of the code sees a title list string. The rest of the code needs it to be one or the other. I switched it off, but then switched on title list right before the list-ops. This might not be the best way, but it seems to work.

There's only one list widget now. There was a logic error with !regexp. !regexp returns a list of items that don't match the criteria, but that doesn't mean that aren't other criteria that DO match the criteria. So instead I used the "emptyMessage" for when there were no items that matched. This meant playing with variable names a bit.

HTH
-- Mark

Mat

unread,
Aug 9, 2018, 8:21:06 PM8/9/18
to TiddlyWiki
Mark! I need to study your creation more but a first couple of tests look extremely promising, wow! :-D

Good spotting with the errors too! Will look closer tomorrow.

<:-)

@TiddlyTweeter

unread,
Aug 10, 2018, 7:22:28 AM8/10/18
to tiddl...@googlegroups.com
Ciao Mat & Mark S.

As far as I understand TW code: Mark's solution, on first look, is elegant and economical.

It changes the context in which the regex would run so that the field is already prepped into lines, one item per line. This makes the regex appropriately easy.

FYI to go the route of having to regex the content of a field without it being split down into individual appropriate lines first could involve unneeded Regex Judo. And maybe needing more than one regex. The code would get complexer too as "[[...]]" can't be put directly in the regex in TW. You'd have to do it through a variable (https://tiddlywiki.com/#regexp%20Operator%20(Examples) last example). And since "[character class]" is reserved in regex you'd also have to escape square brackets "[\[\]]".

Worth noting Mark S. also has a PR on Github for an additional "regexps" operator https://github.com/Jermolene/TiddlyWiki5/pull/2963.

Best wishes
Josiah

Mat

unread,
Aug 10, 2018, 7:54:41 AM8/10/18
to TiddlyWiki
Diego Mesa wrote:

Just wanted to bring to your attention Tobias' excellent split plugin:

While an excellent plugin, I'm not sure exactly how you imagine it used in this context?

<:-)

Mat

unread,
Aug 10, 2018, 8:34:23 AM8/10/18
to TiddlyWiki
@Mark

In deed, your code seems to do the job! Excellent and big thanks. I've updated the code at toggle-in-field and added a cred note. I also skipped the item2 parameter - it was too specific for my own use case.

Now... somewhat annoyingly... look what I just found! github issue #1957; Feature: Allowing the results of checkbox widgets to be stored in a list

I haven't quite yet figured out if they got it to work, but I see indications that the tags field would cause problems which is of course solved in our variant. Wonder if that went anywhere.

<:-)

Mat

unread,
Aug 10, 2018, 8:56:17 AM8/10/18
to TiddlyWiki
@TiddlyTweeter wrote:
 
It changes the context in which the regex would run so that the field is already prepped into lines, one item per line. This makes the regex appropriately easy.

That's a good take away for me, possibly phrased something like: Regex on the items after they've been listwidgeted, not the whole input list.

 
Worth noting Mark S. also has a PR on Github for an additional "regexps" operator https://github.com/Jermolene/TiddlyWiki5/pull/2963.

That would in deed be a VERY useful operator. IMO TW is surprisingly lacking when it comes to tools for programmatically manipulating text.


Thanks for input Josiah, here and privately!

<:-)
Reply all
Reply to author
Forward
0 new messages