【问题标题】:Can't get RegExp to match in GWT无法让 RegExp 在 GWT 中匹配
【发布时间】:2013-02-15 23:19:23
【问题描述】:

示例文本: 在公园里,孩子们玩耍。孩子个子高。孩子看着另一个孩子玩耍。

我想匹配第一句中的“child”,第二句和第三句中的“Child”,而不是第三句中的“child”。或者换句话说,匹配“Child”或“child”,但如果以“another”开头,则不匹配

我以为我可以用消极的眼神来做到这一点

 ((?<\!another) [Cc]hild)

但似乎无法获得正确的语法以生成有效的正则表达式。

即使我可以正确地使用语法,我也不确定我是否可以在 GWT 中做到这一点。这是来自 GWT Javadoc 的 sn-p

正则表达式语法中特定于 Java 的构造(例如,[a-z&amp;&amp;[^bc]], (?&lt;=foo), \A, \Q) 仅在纯 Java 实现中有效,在 GWT 实现中无效,...

任何帮助或见解将不胜感激。

更新:

Colin 的回答几乎可行,但并不完全正确。

科林的正则表达式确实匹配“孩子”和“孩子”,而不是像我问的那样匹配“另一个孩子”。不过也有一些问题。

我要做的是匹配“孩子”和“孩子”,这样它们就可以替换为孩子的名字或正确的代词他/她,这取决于孩子的性别。

Colin 的正则表达式的问题在于它匹配“, child” 和“.child”。如果那是文本中的第一个单词,它也不匹配“Child”。例如:

“孩子去了公园。在公园里,孩子在玩耍。孩子很高。孩子看着另一个孩子在玩耍。”

第一个 Child 不匹配。随后的匹配项分别是“, child”、“.child”和“.child”。

我研究了 Colin 想出的正则表达式,试图让它只匹配“child”或“Child”,但无法使其工作。

【问题讨论】:

标签: javascript regex gwt negative-lookbehind


【解决方案1】:

GWT 中的正则表达式与 RegExp JavaScript 具有相同级别的支持,因为它只是 calls on to the native JavaScript classes

鉴于 JavaScript 正则表达式不支持后视或所有格量词,我想不出直接在正则表达式中拒绝“另一个孩子”的方法。

因此,我将编写一个正则表达式,这样,如果“another”出现在“child”之前,那么“another”肯定会匹配;否则,只会匹配“child”。然后,您可以过滤掉超过 5 个字符的匹配项。

RegExp.compile("(?:another +)?[Cc]hild", "g")

请注意,字符串“some children”中的“child”也会被匹配。而如果“another”被嵌入到一个较长的词串中,例如“ranother”1,那么我们就会盲目的拾取该片段。为了防止这种情况,我们需要添加字边界检查\b2:

RegExp.compile("(?:\\banother +)?\\b[Cc]hild\\b", "g")
                   ---           ---        ---
                    |             |          |
            prevent "ranother"  prevent "children"
              from matching        or "nochild"
                                  from matching

您还可以允许使用i 标志进行不区分大小写的匹配(这对于文本来说非常合理)。但是,我将由您决定。

使用上面的正则表达式,我们总是会在匹配“child”之前匹配“another child”。因此,当匹配只包含“child”时,我们知道“another”不会在它之前。因此,我们可以过滤掉长度 > 5 的匹配项,只剩下有效的字符串。

脚注

  1. 我用一个虚构的词作为例子。在任意字符串中是完全正常的,但我不知道英文中是否有嵌入“another”的单词。

  2. 这里有一个警告。当使用\b 时,“child4”或“child_something”将不匹配。而“_another child”或“5another child”中的“another”不会被正则表达式拾取(并且只有“child”匹配,这意味着您接受匹配)。有可能解决这个问题,如果您要求,我会这样做。

【讨论】:

  • 这与我作为示例给出的文本完全不匹配。它不匹配任何东西。科林的答案很接近,但并不完全按照我需要的方式工作。
  • 我测试了您的带有单词边界的正则表达式,但它与任何内容都不匹配。我刚刚意识到它不起作用,因为当它应该是“\b”时,你转义了单词边界“\\b”。它现在可以匹配孩子、孩子和“另一个孩子”。如果这对我有用,我必须考虑使用长度> 5 的匹配匹配。
  • @nlv:我觉得 \b 起作用很奇怪,因为 Java 字符串中的 \b 是退格字符。根据这个推理,\\b 应在内部解释为正斜杠 + b,然后将其馈送到 RegExp 对象。
  • 正斜杠 + b?你不是说反斜杠 + b吗? compile 方法不是已弃用吗?为什么要使用它而不是 RegExp 构造函数?
  • Alan,Java/GWT Regex 类最终被编译为 JavaScript,而这里使用的静态方法最终只是对您链接的构造函数的调用 - 请参阅 code.google.com/p/google-web-toolkit/source/browse/trunk/user/… 了解如何已实施。
【解决方案2】:

匹配“Child”或“child”,但如果以“another”开头则不匹配

([^(?:another)] [Cc]hild)

这会捕获一个不以another 开头的组(使用非捕获组的否定字符集),然后是一个空格,然后是单词child,无论是否大写。空间有要求吗?您在原始版本中拥有它,并且它出现在您的示例中的所有四个测试用例中。让这个稍微有用一点(你实际上想捕捉什么?),围绕孩子开始唯一的捕捉组:

[^(?:another)] ([Cc]hild)

使用 MDN 文档了解支持的浏览器正则表达式功能:https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions

测试用例:

public void testHomeworkRegex() {
  String sample = "In the park, child plays. Child is tall. Child watches another child at play.";
  RegExp regex = RegExp.compile("[^(?:another)] ([Cc]hild)", "g");//using global flag to match multiple times

  MatchResult result1 = regex.exec(sample);
  assertNotNull(result1);
  assertEquals("child", result1.getGroup(1));

  MatchResult result2 = regex.exec(sample);
  assertNotNull(result2);
  assertEquals("Child", result2.getGroup(1));

  MatchResult result3 = regex.exec(sample);
  assertNotNull(result3);
  assertEquals("Child", result3.getGroup(1));


  MatchResult result4 = regex.exec(sample);
  assertNull(result4);
}

【讨论】:

  • 我认为你不知道你在用正则表达式做什么。尝试使用字符串Child for child no child。您将无法匹配最后 2 个。
  • 这个正则表达式比 nhahtdd 的效果更好,但它仍然存在问题。它匹配句号或逗号以及孩子前面的空格。如果这是文本中的第一个单词,它也不匹配 Child。 nhahtdh 是正确的,这个正则表达式与他给出的字符串完全不匹配。
  • 如果这个正则表达式似乎工作得更好,那是因为你没有严格测试它。 [^(?:another)] 只匹配一个字符,可以是除(?:anoth、@98765437@之外的任何字符987654338@,或)。它只查看前一个单词的最后一个字符,如果是上面列出的字符之一,则匹配失败。
  • Alan Moore,谢谢,你是对的,我显然记错了字符集是如何工作的。我曾假设因为您在another 之后轻松构建了一个不接受child 的FSM,所以我可以使用此语法在正则表达式中描述同一台机器。感谢您指出这一点,我希望更新此答案或添加指出我的错误的注释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-11
  • 1970-01-01
  • 2011-08-03
  • 2016-04-19
  • 1970-01-01
  • 1970-01-01
  • 2018-12-15
相关资源
最近更新 更多