通过URL传递正则表达式

huangapple go评论82阅读模式
英文:

Pass a Regular Expression via URL

问题

我有一个类似这样的资源端点:'.../rest/regex/{regex:.+}/matches{value:.+}';
我如何安全地将正则表达式传递到URL?我该如何对其进行编码?

在 JavaScript 中,我尝试这样做:

        public matches(regex: string, value: string): ng.IPromise<boolean> {
            return this.RestService.httpGet(this.path +  this.escapeRegExp(regex) +
                '/matches/' + encodeURIComponent(value));
        }

        escapeRegExp(str: string) {
            return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\$&');
        }

但是,当我使用这个正则表达式:TNGSXGIN02BZ0(1|3)[1][8-9][0-5][0-9]\d{4} 时,在服务器端(Java)我会得到这个错误:
java.util.regex.PatternSyntaxException: Unclosed counted closure near index 60 (?i)^TNGSXGIN02BZ0/(1/|3/)/[1/]/[8/-9/]/[0/-5/]/[0/-9/]/d/{4/}$

Java 代码如下:

@Path("regex")
@RunInTransaction
@Produces(MediaType.TEXT_PLAIN)
public final class RegexService {
    private static final Logger LOG = Log.getLogger();

    @GET
    @Path("{regex:.+}/matches/{value:.+}")
    public boolean matches(@PathParam("regex") String regex, @PathParam("value") String value) {
        LOG.debug("GET Test regex: {} with value: {}", regex, value);
        return Pattern.matches("(?i)^" + regex + "$", value);
    }
}

更新:
当我在 JavaScript 中这样写:

        public matches(regex: string, value: string): ng.IPromise<boolean> {
            return this.RestService.httpGet(this.path +  encodeURIComponent(regex) +
                '/matches/' + encodeURIComponent(value));
        }

以及在 Java 中这样写:

    @GET
    @Path("{regex:.+}/matches/{value:.+}")
    public boolean matches(@PathParam("regex") String regex, @PathParam("value") String value) {
        LOG.debug("GET Test regex: {} with value: {}", URLDecoder.decode(regex, StandardCharsets.UTF_8), value);
        return Pattern.matches("(?i)^" + URLDecoder.decode(regex, StandardCharsets.UTF_8) + "$", value);
    }

我仍然会得到一个异常:

(?i)^TNGSXGIN02BZ0/(1/|3/)/[1/]/[8/-9/]/[0/-5/]/[0/-9/]/d/{4/}$```

<details>
<summary>英文:</summary>

I have resource endpoint like this: &#39;.../rest/regex/{regex:.+}/matches{value:.+}&#39;;
How can i safely pass the regex in the url? How do I encode it?


In javascript I tried to do: 
```javascript
        public matches(regex: string, value: string): ng.IPromise&lt;boolean&gt; {
            return this.RestService.httpGet(this.path +  this.escapeRegExp(regex) +
                &#39;/matches/&#39; + encodeURIComponent(value));
        }

        escapeRegExp(str: string) {
            return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, &#39;\$&amp;&#39;);
        }

But when I use this regex: TNGSXGIN02BZ0(1|3)[1][8-9][0-5][0-9]\d{4} then server-side (java) i get this error:
java.util.regex.PatternSyntaxException: Unclosed counted closure near index 60
(?i)^TNGSXGIN02BZ0/(1/|3/)/[1/]/[8/-9/]/[0/-5/]/[0/-9/]/d/{4/}$

Java code looks like this:

@Path(&quot;regex&quot;)
@RunInTransaction
@Produces(MediaType.TEXT_PLAIN)
public final class RegexService {
    private static final Logger LOG = Log.getLogger();

    @GET
    @Path(&quot;{regex:.+}/matches/{value:.+}&quot;)
    public boolean matches(@PathParam(&quot;regex&quot;) String regex, @PathParam(&quot;value&quot;) String value) {
        LOG.debug(&quot;GET Test regex: {} with value: {}&quot;, regex, value);
        return Pattern.matches(&quot;(?i)^&quot; + regex + &quot;$&quot;, value);
    }
}

UPDATE:
When i have this in javascript:

        public matches(regex: string, value: string): ng.IPromise&lt;boolean&gt; {
            return this.RestService.httpGet(this.path +  encodeURIComponent(regex) +
                &#39;/matches/&#39; + encodeURIComponent(value));
        }

And this in Java:

    @GET
    @Path(&quot;{regex:.+}/matches/{value:.+}&quot;)
    public boolean matches(@PathParam(&quot;regex&quot;) String regex, @PathParam(&quot;value&quot;) String value) {
        LOG.debug(&quot;GET Test regex: {} with value: {}&quot;, URLDecoder.decode(regex, StandardCharsets.UTF_8), value);
        return Pattern.matches(&quot;(?i)^&quot; + URLDecoder.decode(regex, StandardCharsets.UTF_8) + &quot;$&quot;, value);
    }

I still get an exception:
>java.util.regex.PatternSyntaxException: Unclosed counted closure near index 60
(?i)^TNGSXGIN02BZ0/(1/|3/)/[1/]/[8/-9/]/[0/-5/]/[0/-9/]/d/{4/}$

答案1

得分: 2

你需要对你的正则表达式进行 URL 编码和解码。

对于 JavaScript 编码:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

对于 Java 中的解码:https://docs.oracle.com/javase/7/docs/api/java/net/URLDecoder.html

英文:

You need to URL encode & decode your regex.

For Javascript encoding: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

For decoding in Java: https://docs.oracle.com/javase/7/docs/api/java/net/URLDecoder.html

答案2

得分: -1

可以还使用 String 构造函数:

let regex = new RegExp(".*", "g");
let urlRegex = encodeURIComponent(String(regex));
console.log(urlRegex);

let regexresult = new RegExp(decodeURIComponent(urlRegex));
console.log(decodeURIComponent(urlRegex));
英文:

You can also make use of the String constructor:

let regex = new RegExp(&quot;.*&quot;, &quot;g&quot;);
let urlRegex = encodeURIComponent(String(regex));
console.log(urlRegex);

let regexresult = new RegExp(decodeURIComponent(urlRegex));
console.log(decodeURIComponent(urlRegex));

huangapple
  • 本文由 发表于 2020年10月19日 18:01:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/64425118.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定