Hashtags in frontmatter

I would like to put quotes around tags in frontmatter so that I can include a hashtag in front of the tag eg. “#tag1” so that the tags are searchable in other programs. c.f. Tags In Front Matter, dataview and search #confused - Help - Obsidian Forum

I’ve tried getting a regex from a couple of AI search engines. I’ve asked for a regex to change all words between “tags:” and “links:” , the next element in my frontmatter i.e. to add ‘"#’ before the tag and a ‘"’ after.
Any ideas on this?

this has been asked before

you can give this a shot:

Thanks for your response. I believe the solution you referenced is only good for newly created tags. I would like to be able to add a “#” to all existing frontmatter tags.

You can. In Source Mode just type it like you did here (make sure the quote marks are straight, not curly). In the properties editor (the default in Live Preview, with autocomplete suggestions), just type the hash — the editor will quote the tag for you.

Sorry, in my original post I was not clear. I want to be able to change existing frontmatter tags so that they have a hashtag in front of them.

then you need a search and replace solution…outside of Obsidian
but you’ll need to use regular expressions otherwise it’s tedious…
please attach some of your files’ frontmatter to show what type of syntax for arrays you are employing for tags

as the moderator above hinted, you may only need to add a hashtag and the quotes will be added by the app when you open a markdown file – dunno, one can try in a test vault first

Here is a typical example of what this section of my front matter would look like in Source Mode:

  • glory
  • beauty
    So I want to be able to search for tags in other programs i.e. search for #glory or #beauty. If I search now, I only get the ones with a hashtag which are located in the body of the file, not the frontmatter ones. As you say, I’ll need a regex, I believe.

not good regex

okay, my previous message was:
maybe run in obsidian search first:
/( - )(.+)(?=[\s\S]+links:)/
if it looks to find all well
you can go to notepad++ or vscode and add your vault folder and run match ( - )(.+)(?=[\s\S]+links:) with replacement $1#$2 (note here there is no slashes in the match regex as needed for obsidian search)

if sometimes it’s not links: coming after tags, you can exchange links: in the regex match with whatever comes after (date created or whatever

this is not good because if you have other props above tags with the same list, they get exchanged as well
but if i want to target tags:, no matter what i do i can only capture the first or last of the tags values

if someone with better regex skill don’t come here, you can still use the above

before you do, tho:

  • install and enable linter
  • in yaml section (second leaf) set order of properties in such a way that tags key is on top and any other like aliases, topics, projects is below tags, like i did here now:

run linter on full vault
this will put the tags on top
then you can do all the replacements like i wrote above

finally, you can go undo the linter thing placing aliases, whatever above tags back again

this is hacky but will do the thing for you

p.s.: before - there are two spaces, not one, but this forum doesn’t do justice to whitespaces???

I’m sorry but my regex expertise is pretty weak so I cannot help OP with that.

With a Python script one could use two dumber regexes (match and replace within match for tags section), but setting up Python is a bit of a pain.

Maybe some way with a Dataview + Templater method could also work within Obsidian but I doubt if anyone will write the script (I can’t).
The above workaround with linting first can work. I have recommended the plugin many times before.

Notepad++ tutorials can be found on the net, even in several StackOverFlow answers as well, or here, although that was for a different use case.

Alternatively, OP can put up a question for this use case on StackOverFlow. I have had good people help me out before there when I knew nothing about stuff like this.

Great, thanks a lot. I’ll give this a try. ttyl

OK thanks for the response. I haven’t delved much into Python but like you say, checking out Notepad++ tutorials could be profitable

Yurcee in the screenshot there should have put tags first and links second, BTW. If it’s always links coming after tags in the order of properties in your files.

I had my fair share of regex problems in the past and the chat robots are not really savvy on more elaborate ones.
But with chatGPT I have successfully managed to whomp together working Python scripts I am using daily.

The advantage of scripts over one-liner regexes is that you can filter for smaller chunks (sections of YAML), then perform replace operations in them.

Python envs are worth setting up for working with Obsidian vaults and AI can help with that on any platform (Linux is easier maybe).

Thanks gino_m. I will definitely take a look at getting more into Python. As I think about it, you’re right about AI and python. In my very limited experience it did work whereas it doesn’t work well at all with regex.

Okay, after setting up your Python environment (some cheap robot can help), you can try this script:

import os
import platform
import re

# Set root directory based on platform
if platform.system() == "Windows":
    root_directory = r'C:\Users\<username>\Documents\Obsidian\TEST'
elif platform.system() == "Linux":
    root_directory = '/home/<username>/Documents/Obsidian/TEST'
    # Placeholder for macOS
    root_directory = '/path/to/Macintosh/Obsidian/TEST'

# Regex to find the tags section and ensure section ends when a line does not start with '  - '
tags_section_regex = re.compile(r'(tags:\n(?:\s{2}- .+\n)*)(?=\S)')

# Regex to add # and quotes unless they have been dealt with before
tag_value_regex = re.compile(r'(\s{2}- )(?!"#)(.+)')

# Function to process a single file
def process_file(filepath):
    with open(filepath, 'r', encoding='utf-8') as file:
        content = file.read()
    # Find and process each tags section
    def replace_tags_section(match):
        tags_section = match.group(1)
        modified_tags_section = tag_value_regex.sub(r'\1"#\2"', tags_section)
        return modified_tags_section

    new_content = tags_section_regex.sub(lambda match: replace_tags_section(match), content)

    with open(filepath, 'w', encoding='utf-8') as file:

# Walk through all files in the root directory
for root, dirs, files in os.walk(root_directory):
    for file in files:
        if file.endswith('.md'):  # Assuming markdown files
            process_file(os.path.join(root, file))

print("Processing complete.")

Depending on your OS, you set your path where your (test) vault is. So <username> is one place you need to edit and probably Documents or some other folder if it’s not the same as in the example path.

Running the script will replace - sometag with - "#sometag" in the YAML of markdown files in your vault’s folders and subfolders recursively.

If you were to stick with the Notepad++ method, you can use (tags:\n(?:\s{2}- .+\n)*)(?=\S) , then you’d want to mark the results and do the second step, (\s{2}- )(?!"#)(.+) matching in the marked results, then replacement with $1"#$2", but frankly, I did this sort of 2 step thingy in Notepad++ 2 years ago and I don’t remember the proper steps. Just saying it would be possible and prolly AI can walk you through it. That’s if you shied away from Python. – Which would be handy in the future, as you know.

Made elaborate regex easier which would support any user’s use case (YAML).
Also used \s{2} for two whitespaces as forum markdown shows one space where there is actually two.

yeah, sorry, i meant to do that…brrr…

so this script works with two regexes… yeah… one regex may be impossible…

so, OP doesn’t need to do linter trick now, this should work out of the box

Using Linter is not necessary.

Also, in the meantime I simplified the regex so the script can be used by anyone at all.

Thanks gino_m. The Python process finished but didn’t change anything.
With NotePad++ I got very partial results.
Thanks for your help. I really appreciate it. I have 3 folders with files that need to be changed. I’m doing 2 of them by hand. The third one I don’t care about that much. So please don’t bother spending any time on it for me at least.