كيف يمكنك استخدام تعبير عادي لتجاهل السلاسل التي تحتوي على سلسلة فرعية محددة؟
-
22-08-2019 - |
سؤال
كيف يمكنني استخدام تعبير عادي سلبي (أو أي طريقة أخرى) لتجاهل السلاسل التي تحتوي على سلسلة فرعية معينة؟
لقد قرأت سؤالين سابقين حول تدفق المكدس:
Java-regexp لتصفية الملفات
regex-to-match-ضد-شيء-ليس-سلسلة فرعية محددة
هم تقريبا ماذا اريد...مشكلتي هي أن السلسلة لا تنتهي بما أريد تجاهله.إذا فعلت ذلك فلن تكون هناك مشكلة.
لدي شعور بأن هذا يتعلق بحقيقة أن عمليات البحث تكون ذات عرض صفري وأن شيئًا ما يتطابق في التمريرة الثانية عبر السلسلة ...لكنني لست متأكدًا تمامًا من الأمور الداخلية.
على أية حال، إذا كان أي شخص على استعداد لأخذ الوقت وشرح ذلك فسوف أقدر ذلك كثيرًا.
فيما يلي مثال لسلسلة إدخال أريد تجاهلها:
192.168.1.10 - - [08/Feb/2009:16:33:54 -0800] "الحصول على /FOO/BAR/ HTTP/1.1" 200 2246
فيما يلي مثال لسلسلة إدخال أريد الاحتفاظ بها لمزيد من التقييم:
192.168.1.10 - - [08/Feb/2009:16:33:54 -0800] "الحصول على /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();
}
}
المحلول
هل يمكن أن تطابق تماما أي مسار لا ينتهي مع /
String inRegEx = "^.* \"GET (.*[^/]) HTTP/.*$";
ويمكن أيضا أن يتم ذلك باستخدام <م> lookbehind السلبي م>
String inRegEx = "^.* \"GET (.+)(?<!/) HTTP/.*$";
وهنا، يقول (?<!/)
"في السابقة م> تسلسل يجب أن <م> لا م> مباراة /
".
نصائح أخرى
وربما أنا شيء مفقود هنا، ولكن لا يمكن أن تذهب فقط دون أي تعبير منتظم، وتجاهل أي شيء عن هذا الذي هو الصحيح:
string.contains("/ HTTP")
ولأن مسار الملف لن تنتهي أبدا بخط مائل.
وأود أن استخدام شيء مثل هذا:
"\"GET /FOO/BAR/[^ ]+ HTTP/1\.[01]\""
وهذا يطابق كل مسار هذا ليس مجرد /FOO/BAR/
.
إذا كنت تكتب Regex بهذا التعقيد، فإنني أوصي ببناء مكتبة من الموارد خارج StackOverflow.