Алгоритм определения количества набранных слов, а также поддержка нескольких предложений (Java) - PullRequest
1 голос
/ 30 апреля 2010

Проблема:

Я должен разработать алгоритм, который делает для меня следующее:

Скажи, что у меня есть строка (например)

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>

return -1 (максимум набираемого текста 7 слов)

alert tcp 192.168.1.1 any<caret> 

вернуть 4 (как это все еще на 2-м аргументе)

alert tcp<caret>

возврат 2 (как и во втором аргументе)

alert tcp <caret>

возврат 3

alert tcp $EXTERNAL_NET any -> <caret>

возврат 6

Это что-то вроде команд оболочки. Как указано выше. Хотя я думаю, что это не сильно отличается, я верю, я просто хочу знать, сколько аргументов набрано. Спасибо.

-

псевдокод

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

Ответы [ 4 ]

3 голосов
/ 30 апреля 2010

Используется 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 голос
/ 30 апреля 2010

Коды, предоставляемые полигеномаслами и гелиями, в определенной степени работают.Он решает вышеупомянутую проблему, о которой я говорил, но не с несколькими строками.Код helios более прост.

Однако оба кода не решают проблему, когда вы нажимаете ввод в JTextPane, он все равно вернет старый счет вместо 1, поскольку split() возвращает его как одно предложение вместоиз двух.

Например 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() анализирует строку, "$" создаст еще одну строку, которая будет последней строкой независимо от этого, и счетчик теперь вернется к единице.Кроме того, не будет NullPointerException, поскольку "$" всегда присутствует.

Однако, без помощи полигенных смазок и гелий, я не думаю, что смогу понять это так скоро.Спасибо, ребята!

РЕДАКТИРОВАТЬ: Хорошо ... очевидно, split("\r?\n|\r",-1) работает так же.Вопрос в том, стоит ли мне принимать полигеновые смазки или свои?Хм.

2-е РЕДАКТИРОВАНИЕ: Одна вещь плохая в конкатенации '%' к концу строки, lastLine.endsWith(" ") == true вернет false.Так что придется использовать split("\r?\n|\r",-1) и lastLine.endsWith(" ") == true для полного решения.

1 голос
/ 30 апреля 2010

Как насчет этого: получить последнюю строку, посчитать, что находится между пробелами ...

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 ("")), поэтому вы начинаете новое слово или что-то еще, это базовый подход для вас, чтобы сделать это :)

0 голосов
/ 30 апреля 2010

Является ли образец линии образца? Редактор для некоторого языка на основе правил (ACL)?

Как насчет полного решения по извлечению информации / именованным объектам, которое сможет распознавать объекты (ключевые слова, IP-адреса и т. Д.)? Вам не нужно писать все с нуля, есть инструменты и библиотеки.

ОБНОВЛЕНИЕ : Вот фрагмент кода Snort , который, как я считаю, выполняет анализ:

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 «слов», поэтому ваш алгоритм должен иметь немного больше знаний, верно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...