您将如何使用正则表达式来忽略包含特定子字符串的字符串?

Posted

技术标签:

【中文标题】您将如何使用正则表达式来忽略包含特定子字符串的字符串?【英文标题】:How would you use a regular expression to ignore strings that contain a specific substring? 【发布时间】:2010-10-06 12:54:17 【问题描述】:

如何使用否定的lookbehind(或任何其他方法)正则表达式来忽略包含特定子字符串的字符串?

我已经阅读了之前的两个 *** 问题:java-regexp-for-file-filteringregex-to-match-against-something-that-is-not-a-specific-substring

它们是我想要的几乎...我的问题是字符串没有以我想要忽略的结尾。如果是这样,这将不是问题。

我感觉这与环视是零宽度的事实有关,并且在第二次通过字符串时匹配... 但是,我不太确定内部结构。

无论如何,如果有人愿意花时间解释一下,我将不胜感激。

这是一个我想忽略的输入字符串示例:

192.168.1.10 - - [08/Feb/2009:16:33:54 -0800] "GET /FOO/BAR/HTTP/1.1" 200 2246

这是一个输入字符串的示例,我想保留它以供进一步评估:

192.168.1.10 - - [08/Feb/2009:16:33:54 -0800] "GET /FOO/BAR/content.js HTTP/1.1" 200 2246

对我来说,关键是我想忽略任何在文档根默认页面之后的 HTTP GET。

以下是我的小测试工具,也是迄今为止我想出的最好的 RegEx。

public static void main(String[] args)
String inString = "192.168.1.10 - - [08/Feb/2009:16:33:54 -0800] \"GET /FOO/BAR/ HTTP/1.1\" 200 2246";
//String inString = "192.168.1.10 - - [08/Feb/2009:16:33:54 -0800] \"GET /FOO/BAR/content.js HTTP/1.1\" 200 2246";
//String inString = "192.168.1.10 - - [08/Feb/2009:16:33:54 -0800] \"GET /FOO/BAR/content.js HTTP/"; // This works
//String inString = "192.168.1.10 - - [08/Feb/2009:16:33:54 -0800] \"GET /FOO/BAR/ HTTP/"; // This works
String inRegEx = "^.*(?:GET).*$(?<!.?/ HTTP/)";
try 
  Pattern pattern = Pattern.compile(inRegEx);

  Matcher matcher = pattern.matcher(inString);

  if (matcher.find()) 
    System.out.printf("I found the text \"%s\" starting at " +
"index %d and ending at index %d.%n",
matcher.group(), matcher.start(), matcher.end());
   else 
    System.out.printf("No match found.%n");
  
 catch (PatternSyntaxException pse) 
  System.out.println("Invalid RegEx: " + inRegEx);
  pse.printStackTrace();


【问题讨论】:

所以,您只对明确请求“文件”的内容(例如 /path/to/file.txt)感兴趣,而不是指向“目录”的内容(例如 /path/to /) 请求的 URI 是否以某些“扩展名”(在您的示例中为 .js)结尾? 第一个问题正确。我只想要“文件”而不是“目录”。文件名和扩展名无关紧要......只想忽略对文档根目录的请求 【参考方案1】:

你能匹配任何不以/结尾的路径

String inRegEx = "^.* \"GET (.*[^/]) HTTP/.*$";

这也可以使用消极的lookbehind来完成

String inRegEx = "^.* \"GET (.+)(?<!/) HTTP/.*$";

这里,(?&lt;!/) 表示“前面的序列必须匹配/”。

【讨论】:

谢谢扎克。这非常有效,我相信它比环顾四周表现要好得多。现在,为了我自己的启迪,是否可以使用环视和 java regex 引擎?【参考方案2】:

也许我在这里遗漏了一些东西,但你不能不使用任何正则表达式并忽略任何符合此条件的内容:

string.contains("/ HTTP")

因为文件路径永远不会以斜线结尾。

【讨论】:

【参考方案3】:

我会使用这样的东西:

"\"GET /FOO/BAR/[^ ]+ HTTP/1\.[01]\""

这匹配不只是 /FOO/BAR/ 的所有路径。

【讨论】:

【参考方案4】:

如果您正在编写如此复杂的正则表达式,我建议您在 *** 之外构建一个资源库。

Java Regular Expressions by Mehran Habibi (Apress) Mastering Regular Expressions, Second Edition RegExLib

【讨论】:

感谢您的出色建议...奇怪的是,我有弗里德尔的书和哈比比的书,但我太无知了,无法在阅读有关主题时辨别出整个负面的后视(一般环顾四周)。一般来说,我从这两个来源获得大部分东西。但是这个让我很困惑! 虽然是一个有用的评论,但它并不是问题的真正答案。建议将其更改为评论。

以上是关于您将如何使用正则表达式来忽略包含特定子字符串的字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用正则表达式将特定子字符串提取到新行中?

如何使用正则表达式将特定的子字符串提取到新行中?

如何使用正则表达式搜索忽略 NSPredicate 的某些字符?

使用正则表达式忽略特定字符串

使用 RegEx 忽略分隔符前的特定字符

查找忽略指定字符的子字符串