Javascript Can';t获取要在GWT中匹配的RegExp
示例文本: 在公园里,孩子们玩耍。这孩子很高。孩子看着另一个孩子玩耍 我想在第一句中匹配“child”,在第二句和第三句中匹配“child”,但在第三句中匹配“child”。或者换句话说,匹配“Child”或“Child”,但如果以“other”一词开头,则不匹配 我想我可以用消极的回头看Javascript Can';t获取要在GWT中匹配的RegExp,javascript,regex,gwt,negative-lookbehind,Javascript,Regex,Gwt,Negative Lookbehind,示例文本: 在公园里,孩子们玩耍。这孩子很高。孩子看着另一个孩子玩耍 我想在第一句中匹配“child”,在第二句和第三句中匹配“child”,但在第三句中匹配“child”。或者换句话说,匹配“Child”或“Child”,但如果以“other”一词开头,则不匹配 我想我可以用消极的回头看 ((?<\!another) [Cc]hild) (? 匹配“Child”或“Child”,但如果以单词“other”开头,则不匹配 这捕获了一个不是以另一个(使用非捕获组的否定字符集)开头的组,然
((?<\!another) [Cc]hild)
(?
匹配“Child”或“Child”,但如果以单词“other”开头,则不匹配
这捕获了一个不是以另一个
(使用非捕获组的否定字符集)开头的组,然后是一个空格,然后是单词子
,大写与否。空格是一项要求吗?您在原稿中有此要求,并且在您的示例中的所有四个测试用例中都有此要求。这会稍微有用一些(你到底想捕捉什么?),开始围绕孩子的唯一捕捉小组:
[^(?:another)] ([Cc]hild)
在受支持的浏览器正则表达式功能上使用MDN文档:
测试用例:
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);
}
GWT中的正则表达式具有与RegExp JavaScript相同的支持级别,因为它只是
考虑到JavaScript正则表达式不支持look-behind或所有格量词,我想不出一种直接在正则表达式中拒绝“另一个孩子”的方法
因此,我将编写一个正则表达式,这样,如果“另一个”出现在“child”之前,那么“另一个”肯定会被匹配;否则,只有“child”会被匹配。然后,您可以过滤掉超过5个字符的匹配
RegExp.compile("(?:another +)?[Cc]hild", "g")
请注意,字符串“some children”中的“child”也将被匹配。如果“other”嵌入较长的单词字符串中,例如“ranother”1,则我们将盲目地拾取片段。为了防止这种情况,我们需要添加单词边界检查\b
2:
您还可以允许使用i
标志进行不区分大小写的匹配(这对于文本来说非常合理)。但是,我将由您决定
使用上面的正则表达式,我们总是在匹配“child”之前匹配“other child”。因此,当匹配只包含“child”时,我们知道“other”不在其前面。因此,我们可以过滤掉长度大于5的匹配,只剩下有效字符串
脚注
我以一个虚构的单词为例,它在任意字符串中都是完全正常的,但我不知道英语中是否有嵌入“另一个”的单词
这里有一个警告。当使用\b
时,“child4”或“child\u something”将不匹配。而正则表达式将不会提取“\u other child”或“5other child”中的“other”(另一个)(并且只有“child”匹配,这意味着您接受匹配).有可能解决这个问题,如果你要求的话,我会做的
这可能会对您有所帮助。我认为您不知道如何使用正则表达式。请尝试使用字符串Child for Child no Child
。您将无法匹配最后2个。此正则表达式比nhahtdd的更好,但仍然存在问题。它在句点或逗号以及Child前面的空格上匹配。它也与Child I不匹配f这是文本中的第一个单词。nhahtdh是对的,这个正则表达式与他给出的字符串完全不匹配。如果这个正则表达式似乎工作得更好,那是因为您没有严格测试它。[^(?:另一个)]
只匹配一个字符,可以是除(
,?
,:
,a
,n
,o
,t
,h
,e
,r
,或)
。它只查看前一个单词的最后一个字符,如果它是上面列出的字符之一,匹配将失败。艾伦·摩尔,谢谢,你说得对,我显然忘记了字符集是如何工作的。我曾假设,因为你很容易构建一个FSM,在另一个之后不接受子,所以我可以用这个语法在正则表达式中描述同一台机器。感谢您指出这一点,我希望更新这个答案或添加一个注释指出我的错误。这与我作为示例给出的文本完全不匹配。它与任何内容都不匹配。科林的答案很接近,但并不完全符合我的需要。我测试了您的答案gex有单词边界,但它在任何方面都不匹配。我刚刚意识到它不起作用,因为您在单词边界应为“\b”时跳过了“\\b”。它现在可以在匹配子、子和“另一个子”时起作用。如果对我有效,我必须考虑使用长度大于5的匹配项。@nlv:我发现\b
工作起来很奇怪,因为Java字符串中的\b
是退格字符。根据这个推理,\\b
应该在内部解释为正斜杠+b
,然后将其输入RegExp对象。正斜杠+b
?你不是说反斜杠+b
?而且compile
方法不是被弃用了吗?为什么要用它来代替RegExp
构造函数呢?Alan,Java/GWT Regex类最终被编译成JavaScript,而这里使用的静态方法最终只是对链接到-s的构造函数的调用请参阅如何实现。
RegExp.compile("(?:another +)?[Cc]hild", "g")
RegExp.compile("(?:\\banother +)?\\b[Cc]hild\\b", "g")
--- --- ---
| | |
prevent "ranother" prevent "children"
from matching or "nochild"
from matching