Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

requiredIf/oneOf multi-word strings containing single quotes? #1350

Open
2 tasks done
fiendish opened this issue Dec 20, 2024 · 0 comments
Open
2 tasks done

requiredIf/oneOf multi-word strings containing single quotes? #1350

fiendish opened this issue Dec 20, 2024 · 0 comments

Comments

@fiendish
Copy link

fiendish commented Dec 20, 2024

  • I have looked at the documentation here first?
  • I have looked at the examples provided that may showcase my question here?

Package version eg. v9, v10:

v10

Issue, Question or Enhancement:

The simple regex for splitting params using single quotes to encapsulate multiple words that was added in #541 appears to break on strings that contain single quotes. How do we escape them?

Code sample, to showcase or reproduce:

package main

import (
	"encoding/json"
	"fmt"

	"github.com/go-playground/validator/v10"
)

type Data struct {
	Stage       *string
	ChurnReason *string `validate:"required_if=Stage <WHAT GOES HERE?>"` // Should be required if Stage == "Churn's Reason"
}

func main() {
	jsonData := []byte(`{"stage": "Churn's Reason"}`)

	var test Data
	_ = json.Unmarshal(jsonData, &test)
	validate := validator.New()
	err := validate.Struct(test)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("No errors")
	}
}

I think rather you want a pattern of '([^']|'')*'|\S+ and then normalization by

for i, match := range matches {
	if len(match) > 1 && match[0] == '\'' && match[len(match)-1] == '\'' {
		// Remove outer single quotes
		match = match[1 : len(match)-1]
		// Replace doubled single quotes with single quote
		match = regexp.MustCompile("''").ReplaceAllString(match, "'")
	}
	matches[i] = match
}

which would allow doubling the quotes up to escape them inside multi-word tokens.


here's a little test

package main

import (
	"fmt"
	"regexp"
)

func tokenize(input string) ([]string, error) {
	re, err := regexp.Compile(`'([^']|'')*'|\S+`)
	if err != nil {
		return nil, fmt.Errorf("failed to compile regex: %w", err)
	}
	matches := re.FindAllString(input, -1)
	if matches == nil {
		return nil, nil
	}
		for i, match := range matches {
		if len(match) > 1 && match[0] == '\'' && match[len(match)-1] == '\'' {
			// Remove outer single quotes
			match = match[1 : len(match)-1]
			// Replace doubled single quotes with single quote
			match = regexp.MustCompile("''").ReplaceAllString(match, "'")
		}
		matches[i] = match
	}
	return matches, nil
}

func main() {
	input := "''''''hello 'single quoted' worl' 'it''s a test' 'another ''example'''"
	tokens, err := tokenize(input)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	for i, token := range tokens {
		fmt.Printf("Token %d: %s\n", i+1, token)
	}
}
Token 1: ''
Token 2: hello
Token 3: single quoted
Token 4: worl'
Token 5: it's a test
Token 6: another 'example'

You can see that between encapsulating pairs of single quotes one could then add doubled single quotes to preserve literal ones.

@fiendish fiendish changed the title requiredIf/oneOf string containing single quotes? requiredIf/oneOf multi-word strings containing single quotes? Dec 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant