Regular Expressions on Template Fields

Things I have tried

I am using templates and pulling in values such as the title through {{title}}

What I’m trying to do

Is there anyway of pulling out a portion of the title field when I apply a template to a note. I have a note title which might be

Term <Key Term>

Ideally I want to pull out the from the title and display it to other areas of the note when the template is applied. Is there anyway of doing this?

It sounds like you’re using the core template plugin, and I think to get the functionality you’re looking for you need to start using the Templater plugin.

In those templates you’re able to do a lot more, like accessing field of the file you came from, set variables for use later in the template insertion, and if you use dynamic execution parts in your template you can execute javascript code with regular expressions (for example).

3 Likes

@holroy solution worked and I’ve managed to pull out the title. Only problem I’m having is how to apply a regex to it. Would I do this in the user script?

https://silentvoid13.github.io/Templater/user-functions/script-user-functions.html

Here is what I would do, and this is using JavaScript Execution Commands, so please take care when running any script like this.

This needs to be placed at the top of your file. The underscores are for whitespace control, you can modify them to fit your purpose. (I might have got the order of the _ and * wrong, try swapping if this doesn’t work)

<%_*
	let title = tp.file.title;
	var keyTerm = '';
	if (title.startsWith("Term ")) {
		// You can use a more complicated extraction system like regex, 
		// but slice should work if you're only extracting the rest of the title
		keyTerm = title.slice(5);
	}
_%>

And then anywhere you want to access that that value, you can insert it by using

<% keyTerm %>
4 Likes

@mr_abomination that’s fantastic. Now up and running and managed to get some regular expressions working.

Do you know if it’s possible to return partial matches for a link as an array?

What precisely do you mean by “partial matches for a link”?

Thanks @mr_abomination. I have notes that the filename have a number and lesson name. Example below.

M01L02 - LESSON NAME

I can find all instances of where M01L02 using Obsidian Query Language. It pulls back all files where the lesson appears but I need the rest of the filename namely the lesson name. In some instances the note exists and in others it is just a mention. In a lot of cases it’s just a mention. Do you know how I might pull it out?

So to further extend on the idea @mr_abomination uses, let’s do a simple regex, and then use that in a query later on.

<%* 
const title = tp.file.title;
let lessonNumber

const matches = title.match(/^(M[0-9]{2}L[0-9]{2})/)
if (matches) {
  // Current title matches, so the number is in matches[1]
  lessonNumber = matches[1]
} else {
  lessonNumber = "no-match"
}
%>

... other parts of your template ...

<%*
if ( lessonNumber != "no-match" ) {
  tR = `
~~~query
${ lessonNumber }
~~~`
}
_%>

A few comments about this, I’m assuming you know your regex since you’ve worded your question as you did. I just wrote a randomish regex to match M + two digits + L + two digits at the start of the string. Correct this according to your needs.

I’m assuming you might want to check the file title at the beginning of the template, and insert the query at a later stage, so I temporarily store the search into lessonNumber or potentially an indicator that no match was found in which case the query will not be written into the end note.

I’ve used ~~~ for the query code block to avoid issues with the ` used for the template string literal. You could opt for \`\`\`, but why bother when tildes work just fine.

I’m not entirely sure if you want to add other stuff to your query, but feel free to adapt. This is just a sketch to show the concept of pulling out something using regex, and using that result later on.

Thanks all. Here is the code I’m running which is returning the file that the mention is in however it is not returning the specifics of the mention which should be.

My regex is:

Regex is: M01L01

The mention in the file is: M01L01 - Lesson Name

The mention folder and filename is:

folder/Filename_of_result.md

What I want to return is:

M01L01 - Lesson Name

Should I be doing something different with files.map?

Below is the code that I’m running

<%*

//const query = "testing";
const query = '/(M01L01 - (.*)/';

// Perform the search 
app.internalPlugins.plugins['global-search'].instance.openGlobalSearch(query);

const searchLeaf = app.workspace.getLeavesOfType('search')[0];
const search = await searchLeaf.open(searchLeaf.view);
const rawSearchResult = await   new   Promise(resolve =>   setTimeout(() => { 
resolve(search.dom.resultDomLookup);
}, 300)); // the delay here was specified in 'obsidian-text-expand' plugin; I assume they had a reason   
   
const files = Array.from(rawSearchResult.keys());

console.log(files.map(x => x.path));

%>

<%
files.map(x => x.path)
%>

This regex should fail, as the parentheses don’t match. Then again, the first should most likely be ^ to match at start of sentence…

Thanks @holroy. I believe the regex is working but it’s just pulling back the title of the note where the match originates from. How do I access the match itself?

Normally, as in my code, the first element, aka [0], is the entire matched string, and should be used to check whether it matched or not, at all. And then the second element, aka [1], is the first capturing group.

Thanks @holroy. Does your code search all of the titles of each note?

Your request was originally just to extract the title from the newly created note for use in that note, so no it doesn’t look into other files.

However, the pattern regarding searches and what is returned from a regex search is usually the same. Hence the suggestion to use [1].

Yet again, you’re introducing code from another plugin, and an API which I’ve not used, so I can’t be extremely confident in saying this would fix all of your problems.

Ahhhh…yes you’re right. Thinking has evolved. Big thanks for your help @holroy.

Let me close this thread down and create one related to Obsidian Query Language.

1 Like