Help wanted with refactoring links

It shouldn’t be a problem to do this in just one step. If the regex is specific enough, and you don’t necessarily do replace all, it should be safe to do.

1 Like

I have a backup :grimacing:
But I don’t understand, if you do it in two steps as you describe, how to determine |term' in my glossary from |aliasin my normal links. The path_terms/` is the differentiator.

Is there a way to get [term](dict://term) links to work on iOS?

Maybe search \[\[terms\/(.*)\|.*\]\] and replace with [$1](dict://$1) the first time around thus taking care of those with pipes. Then the second round search \[\[terms\/(.*)\]\] and replace [$1](dict://$1) but this is just a guess. On my phone and can’t really test.

this doesn’t fuss me. I have access to my vault on my phone but don’t really use it for anything strenuous. I always have my laptop

1 Like

Was being entirely selfish and asking for my own needs. :flushed:

1 Like

OMG!

Regex is \[\[_terms/(.*)\|(.*)\]\]
Replace is [$1](dict://$1)

I just tested it on my phone and no bueno, link doesn’t respond

1 Like

So are you saying it kind of works but perhaps the capitalization is causing issues?

So here goes nothing:

  • search for: \[\[_terms/([^\|\]]*)(?:\|[^\]]*)?\]\]
  • replace with: [\l$1](dict://\L$1)

As an image:

What this aims to do is search for something which in order is:

  • \[\[_terms/ – Always starts with this text
  • ([^\|\]]*) – a capture group of anything up until either a | or a ] bracket character, properly escaped (which makes the regex read a lot harder… )
  • (?:\|[^\]]*)? - an optional non-capturing group with the lead-in character of | followed by anything until the next ] character
  • \]\] – always ending with a double bracket

When it comes to the replacement part it’s simpler:

  • [\l$1] – Place the first capture group within the brackets as the name of the link, with the first character lowercase, \l
  • (dict://\L$1) – And then the actual link also with the first capture group, with the entire group lowercased, \L

Feel free to interchange or use whatever to lowercase, either both or none of them. Just wanted to place them there to show some options.

Preserving the case of your original term would be a little harder, as one one need to change the capture group to be the latter part of the regexp. It is possible but harder. The proposed solution might arise a few issues when your search term is at the start of a sentence, and you do want it to have an uppercase character at front.

A final note on the usage of character classes, i.e. [^\|\]]* and [^\]]*, instead of the ordinary wild card, .: I tend to use this more specific approach to limit my regex so they don’t get overly greedy, and expand into other cases which could occur on the same lines and so on. Just a matter of precautions, which I’ve gotten accustomed to.

Hope this helps,
Holroy

1 Like

Indeed.

Saw your first post: thrilled.

Tried it on my MBA: even more thrilled.

Tried it on my iPhone: %$£#

Searched Google: nada.

Was hoping you or someone in the thread might know how to get this to work across OS platforms.

But still fairly thrilled. Grateful for the tip / share. Useful as the MBA is my main device.

Very neat regex sorcery. Squirrelled that away for a rainy day.

1 Like

Since it is somewhat relevant here, you might be interested in this document I made: Regular Expressions in Obsidian (copied from mdn web docs)

2 Likes

Thanks all,

I pulled the trigger and everything is good. The replace was better as [$2](dict://$1) as the second capture group was the lower case alias and most links were mid-sentence.

I’m stoked at the result - thank you all so much for the input. Happy days!

2 Likes

Did you use the regex from I-d-as? You’re aware that doesn’t pickup the case of [[_terms/Pyrexia]] where there are no alias?

Here is an explanation of your search:

  1. \[\[_terms/ – Matches the double brackets, and the text
  2. (.*) – A capture group catching anything
  3. | - When unescaped this is an alternator, and in your case all of my explanations above is the first alternator group, and all explanations below are the second alternator group
  4. (.*) - A capture group catching anything
  5. \]\] – An actual match on double brackets

So most matches in your image, is doing the alternating match of 4. and 5., that is capture anything before double brackets. This could be avoided by doing \| which instead means to actually match the specific character of | and not it’s (hidden?) alternator meaning.

1 Like

Sorry for still replying, but I wasn’t entirely satisfied with not preserving the case if no alias was given, so I kept pondering away. Explanation of regex.

The new search term is then: \[\[_terms\/(?:([^\]\|]*)\]\]|[^\]\|]*\|([^\]]*)\]\])
with replacement string: [$1$2](dict://$1$2)

I’m not particular fond of the doing $1$2 in the replacement, but the alternator operator and the entire setup of the regex assures that only one of them is set. The same reasoning applies to why the \]\] is duplicated as I needed both alternatives to fully match, to avoid mismatches. Could surely be optimised somehow, but my brain doesn’t see a clear solution just now to that issue. :face_with_spiral_eyes:

Regards,
Holroy

1 Like

Good stuff @holroy. It’s unlikely, but @jonr might have used the two pass technique (I did forget to add the underscore for the _terms folder name, but otherwise the technique may have worked reasonably well, but I’m not sure) :

Thanks for your explanations and commitment to getting things right. I too would be curious what ended up working.

@I-d-as: I just saw that his replacement string was the [$2](dict://$1) which refers to a secondary capturing group, so if that was his only run, it could indicate that he still got cases like the [[_term/Pyrexia]] floating around.

And just to clarify, I don’t really care whichever regex he uses, I just want him to actually get all of the changes he needs. But it’s always good to get a good response from the OP as to how he actually solved his question in the end.

1 Like

Hi,
Sorry I didn’t see these messages earlier. Thanks to everyone for their help.
Yes I used [$2](dict://$1) which solved the case issue as the aliases were all lower case.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.