1

I am trying to redirect the urls to add trailing slash

/news -> /news/
/news?param1=value1 -> /news/?param1=value
/news#anchor?param1=value1 -> /news/#anchor?param1=value1

I need to do it through a regex that identifies only the path and add /. When there are no parameters there is no problem.

^(/[a-z0–9/_\-]*[^/])$ -> $1/

But when there are parameters I am not able to create the regular expression that separates the path from the parameters.

Any ideas?, thanks

  • 1
    The `$` in your regex matches the end of the input (or a line in multiline mode), so it isn't going to match any url with path parameters. – Abion47 Jul 02 '20 at 17:03

5 Answers5

0

You shouldn't match the end of the string with $ and there is no need for [^/] at the end either.

^(/[a-z0–9/_\-]*)

const regex = new RegExp("^(/[a-z0–9/_\-]*)");
console.log("/news".replace(regex, "$1/"));
console.log("/news?param1=value1".replace(regex, "$1/"));
console.log("/news#anchor?param1=value1".replace(regex, "$1/"));
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
0

The pattern you tried matches only /news because the anchor $ asserts the end of the string.

If you omit the anchor, it would also match the ? and # as you use [^/] which matches any char except a forward slash.


You could repeat 1 or more times matching a forward slash followed by 1 or more times any char listed in the character class to prevent matching ///

In the replacement use the full match and add a a forward slash.

^(?:/[a-z0-9_-]+)+

Regex demo | Java demo

String regex = "^(?:/[a-z0-9_-]+)+";
String string = "/news\n"
     + "/news?param1=value1\n"
     + "/news#anchor?param1=value1";

Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(string);
String result = matcher.replaceAll("$0/");

System.out.println(result);

Output

/news/
/news/?param1=value1
/news/#anchor?param1=value1

Note that in your regex, the hyphen in this part 0–9 is

https://www.compart.com/en/unicode/U+2013 instead of https://www.compart.com/en/unicode/U+002D

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
0

Might be just need to extend the end of string past the parameters.
To cover both with and without parameters might be:

^(/[a-z0–9/_-]*(?<!/))([^/]*)$ -> $1/$2

see https://regex101.com/r/Iwl23o/2

  • It has worked perfectly, I have only added that it also accepts capital letters. Thank you very much, I was already going crazy with this problem. – user13854865 Jul 03 '20 at 07:35
0

You can do it as follows:

public class Main {
    public static void main(final String[] args) {
        String[] arr = { "/news", "/news?param1=value1", "/news#anchor?param1=value1" };
        for (String s : arr) {
            System.out.println(s.replaceFirst("([^\\/\\p{Punct}]+)", "$1/"));
        }
    }
}

Output:

/news/
/news/?param1=value1
/news/#anchor?param1=value1

Explanation of the regex:

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
0

You can use a very simple regex like this:

^([/\w]+)

With this replacement string: $1/

Working demo

enter image description here

Federico Piazza
  • 30,085
  • 15
  • 87
  • 123