问题:
我必须设计一个算法,它为我做了以下事情:
说我有一条线(例如)
alert tcp 192.168.1.1 (caret is currently here)
算法应处理此行,并返回值4。
我为它编写了一些东西,我知道它很邋,,但它的确有效。
private int counter = 0;
public void determineRuleActionRegion(String str, int index) {
if (str.length() == 0 || str.indexOf(" ") == -1) {
triggerSuggestionList(1);
return;
}
//remove duplicate space, spaces in front and back before searching
int num = str.trim().replaceAll(" +", " ").indexOf(" ", index);
//Check for occurances of spaces, recursively
if (num == -1) { //if there is no space
//no need to check if it's 0 times it will assign to 1
triggerSuggestionList(counter + 1);
counter = 0;
return; //set to rule action
} else { //there is a space
counter++;
determineRuleActionRegion(str, num + 1);
}
} //end of determineactionRegion()
所以基本上我找到空间并确定区域(键入的单词数)。但是,我希望在用户按空格键<space character>
时更改。
我如何使用当前代码?
或者更好的是,如何建议我以正确的方式执行?我正在为这个案子搞清楚BreakIterator ......
除此之外,我相信我的算法不适用于多句话。 我应该如何处理这个问题。
-
String str的源代码来自textPane.getText(0, pos + 1);
,即JTextPane。
提前致谢。如果我的问题仍然不够具体,请告诉我。
-
更多例子:
alert tcp $EXTERNAL_NET any -> $HOME_NET 22 <caret>
返回-1(键入的文本的最大值为7个单词)
alert tcp 192.168.1.1 any<caret>
返回4(因为它仍处于第2个arg)
alert tcp<caret>
返回2(因为它仍处于第二个arg)
alert tcp <caret>
返回3
alert tcp $EXTERNAL_NET any -> <caret>
返回6
它类似于shell命令。如上。虽然我认为它并没有多大差别我相信,但我只是想知道输入了多少个参数。感谢。
-
伪代码
Get whole paragraph from textpane
if more than 1 line -> process the last line
count how many arguments typed and return appropriate number
else
process current line
count how many arguments typed and return appropriate number
End
答案 0 :(得分:3)
这使用String.split
;我想这就是你想要的。
String[] texts = {
"alert tcp $EXTERNAL_NET any -> $HOME_NET 22 ",
"alert tcp 192.168.1.1 any",
"alert tcp",
"alert tcp ",
"alert tcp $EXTERNAL_NET any -> ",
"multine\ntest\ntest 1 2 3",
};
for (String text : texts) {
String[] lines = text.split("\r?\n|\r");
String lastLine = lines[lines.length - 1];
String[] tokens = lastLine.split("\\s+", -1);
for (String token : tokens) {
System.out.print("[" + token + "]");
}
int pos = (tokens.length <= 7) ? tokens.length : -1;
System.out.println(" = " + pos);
}
这会产生以下输出:
[alert][tcp][$EXTERNAL_NET][any][->][$HOME_NET][22][] = -1
[alert][tcp][192.168.1.1][any] = 4
[alert][tcp] = 2
[alert][tcp][] = 3
[alert][tcp][$EXTERNAL_NET][any][->][] = 6
[test][1][2][3] = 4
答案 1 :(得分:1)
这个怎么样:得到最后一行,计算空格之间的内容......
String text = ...
String[] lines = text.split("\n"); // or \r\n depending on how you get the string
String lastLine = lines[lines.length-1];
StringTokenizer tokenizer = new StringTokenizer(lastLine, " ");
// note that strtokenizer will ignore empty tokens, it is, what is between two consecutive spaces
int count = 0;
while (tokenizer.hasMoreTokens()) {
tokenizer.nextToken();
count++;
}
return count;
编辑你可以控制你是否有一个最后的空格(lastLine.endsWith(“”))所以你开始一个新词或者其他什么,这是你完成它的基本方法: )
答案 2 :(得分:1)
polygenelubricants和helios提供的代码在一定程度上起作用。它解决了我所说的上述问题,但不涉及多行。 helios的代码更直接。
但是当你在JTextPane中输入时,两个代码都没有解决问题,它仍然会返回旧计数而不是1,因为split()
将它作为一个句子而不是两个返回。
E.g。 alert tcp <enter is pressed>
右边它应该返回1,因为它是一个新句子。两个算法都返回2。
此外,如果我突出显示全部并删除两个算法将抛出NullPointerException
,因为没有要拆分的字符串。
我添加了一行,它解决了上面提到的问题:
public void determineRuleActionRegion(String str) {
//remove repetitive spaces and concat $ for new line indicator
str = str.trim().replaceAll(" +", " ") + "$";
String[] lines = str.split("\r?\n|\r");
String lastLine = lines[lines.length - 1];
String[] tokens = lastLine.split("\\s+", -1);
int pos = (tokens.length <= 7) ? tokens.length : -1;
triggerSuggestionList(pos);
System.out.println("Current pos: " + pos);
return;
} //end of determineactionRegion()
这样,当split()
解析str时,"$"
将创建另一行,无论如何都是最后一行,现在计数将返回到一行。此外,由于NullPointerException
始终存在,因此不会"$"
。
但是,如果没有多基因润滑剂和helios的帮助,我认为我不会这么快就弄明白。谢谢你们!
编辑:好的......显然split("\r?\n|\r",-1)
的工作原理相同。问题是我应该接受polygenelubricants还是我自己? HMM。
第二次编辑:将'%'
连接到str的结尾有一点不好,lastLine.endsWith(" ") == true
将返回false
。因此,必须使用split("\r?\n|\r",-1)
和lastLine.endsWith(" ") == true
来获得完整的解决方案。
答案 3 :(得分:0)
样品线是代表性的吗?一些基于规则的语言(ACL)的编辑器?
如何获得完整的信息提取/命名实体识别解决方案,能够识别实体(关键字,IP地址等)?您不必从头开始编写所有内容,而是现有的工具和库。
更新:我认为这是解析的piece of Snort code:
Function ParseRule()
if (*args == '(') {
// "Preprocessor Rule detected"
} else {
/* proto ip port dir ip port r*/
toks = mSplit(args, " \t", 7, &num_toks, '\\');
/* A rule might not have rule options */
if (num_toks < 6) {
ParseError("Bad rule in rules file: %s", args);
}
..
}
otn = ParseRuleOptions(sc, rtn, roptions, rule_type, protocol);
..
mSplit在mstring.c中定义,这是一个将字符串拆分为标记的函数。
在你的情况下,ParseRuleOptions应该为括号内的整个字符串返回一个。
更新2 :顺便说一下,你的第一个例子是正确的,因为在snort中,你可以为规则添加选项吗?例如,这是一个有效的规则(选项部分未完成):
alert tcp any any -> 192.168.1.0/24 111 (content:"|00 01 86 a5|"; <caret>
在某些情况下,你可以有6个或7个'单词',所以你的算法应该有更多的知识,对吗?