I'm trying to turn a JSON format string into parsable URL encoded string.

Here's my process:

" Read the contents of the file separated into lines
let lines = join(getline(1, '$'), '\n')

" Assign an empty string for annotations
let annotations = ''

" Separate markup from content into a list
let contents = split(lines, '\v(\<[^<]*\>|[^<]+)\zs')

" Add contents into annotations in JSON format
for content in contents
  if match(content, '<[^>]*>') > -1
    let annotations .= '{"markup":'
    let annotations .= '{"text":'

  let annotations .= ' "' . content . '"},'

" Generate the JSON output
let json_data = '{"annotation":' . annotations . '}'

This is how the output looks now:

"{\"annotation\":{\"text\": \"Style and grammer checker\"}}"

The desired output would be this:


Thanks for your time!

  • Welcome to Vi and Vim SE. Urlencode a multiline string in VIM, so it can be used to query a search engine on SO seems to be about the same problem. In the comments, there are links to the existing answer as well as to other solutions.
    – Friedrich
    Jul 24, 2023 at 11:04
  • Yup! 😄 The link I provided in the answer is the first in the list. Jul 24, 2023 at 11:15
  • 1
    I think in your previous question you said you weren't parsing HTML, but it sure looks like you might be. I strongly suggest you consider writing this program in another language, and using Vimscript only to coordinate sending text from the editor to it and receiving the results.
    – D. Ben Knoble
    Jul 24, 2023 at 13:19
  • True. I misunderstood the definition of parsing. I had to look at the definition again. Sorry. I thought parsing was a more advance way of dealing with contents. It seemed like what I wanted to do was simpler than what parsing tools do. I've decided to parse the content in a Ruby script instead. Thanks for the advice. The code of my Vimscript looks better now. Jul 24, 2023 at 23:40

1 Answer 1


I found this and it works fine.

" URL encode a string. ie. Percent-encode characters as necessary.
function! UrlEncode(string)

    let result = ""

    let characters = split(a:string, '.\zs')
    for character in characters
        if character == " "
            let result = result . "+"
        elseif CharacterRequiresUrlEncoding(character)
            let i = 0
            while i < strlen(character)
                let byte = strpart(character, i, 1)
                let decimal = char2nr(byte)
                let result = result . "%" . printf("%02x", decimal)
                let i += 1
            let result = result . character

    return result


" Returns 1 if the given character should be percent-encoded in a URL encoded
" string.
function! CharacterRequiresUrlEncoding(character)

    let ascii_code = char2nr(a:character)
    if ascii_code >= 48 && ascii_code <= 57
        return 0
    elseif ascii_code >= 65 && ascii_code <= 90
        return 0
    elseif ascii_code >= 97 && ascii_code <= 122
        return 0
    elseif a:character == "-" || a:character == "_" || a:character == "." || a:character == "~"
        return 0

    return 1

  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
    – Herb
    Jul 24, 2023 at 5:07
  • 1
    Thanks! I just added it to the answer. Jul 24, 2023 at 5:25
  • 1
    Friendly reminder to accept your own answer (if you're so inclined). Would keep Community Bot from bumping this thing every now and then. Thanks.
    – Friedrich
    Apr 19 at 8:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.