通过URL传递正则表达式

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

Pass a Regular Expression via URL

问题

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

在 JavaScript 中,我尝试这样做:

  1. public matches(regex: string, value: string): ng.IPromise<boolean> {
  2. return this.RestService.httpGet(this.path + this.escapeRegExp(regex) +
  3. '/matches/' + encodeURIComponent(value));
  4. }
  5. escapeRegExp(str: string) {
  6. return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\$&');
  7. }

但是,当我使用这个正则表达式: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 代码如下:

  1. @Path("regex")
  2. @RunInTransaction
  3. @Produces(MediaType.TEXT_PLAIN)
  4. public final class RegexService {
  5. private static final Logger LOG = Log.getLogger();
  6. @GET
  7. @Path("{regex:.+}/matches/{value:.+}")
  8. public boolean matches(@PathParam("regex") String regex, @PathParam("value") String value) {
  9. LOG.debug("GET Test regex: {} with value: {}", regex, value);
  10. return Pattern.matches("(?i)^" + regex + "$", value);
  11. }
  12. }

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

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

以及在 Java 中这样写:

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

我仍然会得到一个异常:

  1. (?i)^TNGSXGIN02BZ0/(1/|3/)/[1/]/[8/-9/]/[0/-5/]/[0/-9/]/d/{4/}$```
  2. <details>
  3. <summary>英文:</summary>
  4. I have resource endpoint like this: &#39;.../rest/regex/{regex:.+}/matches{value:.+}&#39;;
  5. How can i safely pass the regex in the url? How do I encode it?
  6. In javascript I tried to do:
  7. ```javascript
  8. public matches(regex: string, value: string): ng.IPromise&lt;boolean&gt; {
  9. return this.RestService.httpGet(this.path + this.escapeRegExp(regex) +
  10. &#39;/matches/&#39; + encodeURIComponent(value));
  11. }
  12. escapeRegExp(str: string) {
  13. return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, &#39;\$&amp;&#39;);
  14. }

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:

  1. @Path(&quot;regex&quot;)
  2. @RunInTransaction
  3. @Produces(MediaType.TEXT_PLAIN)
  4. public final class RegexService {
  5. private static final Logger LOG = Log.getLogger();
  6. @GET
  7. @Path(&quot;{regex:.+}/matches/{value:.+}&quot;)
  8. public boolean matches(@PathParam(&quot;regex&quot;) String regex, @PathParam(&quot;value&quot;) String value) {
  9. LOG.debug(&quot;GET Test regex: {} with value: {}&quot;, regex, value);
  10. return Pattern.matches(&quot;(?i)^&quot; + regex + &quot;$&quot;, value);
  11. }
  12. }

UPDATE:
When i have this in javascript:

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

And this in Java:

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

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 构造函数:

  1. let regex = new RegExp(".*", "g");
  2. let urlRegex = encodeURIComponent(String(regex));
  3. console.log(urlRegex);
  4. let regexresult = new RegExp(decodeURIComponent(urlRegex));
  5. console.log(decodeURIComponent(urlRegex));
英文:

You can also make use of the String constructor:

  1. let regex = new RegExp(&quot;.*&quot;, &quot;g&quot;);
  2. let urlRegex = encodeURIComponent(String(regex));
  3. console.log(urlRegex);
  4. let regexresult = new RegExp(decodeURIComponent(urlRegex));
  5. 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:

确定