Как проверить, содержит ли строка, содержащая «теги», разделенные любым токеном, не состоящим из слов, данный тег в Java - PullRequest
0 голосов
/ 08 апреля 2011

Кто-нибудь знает, как в Java проверить, содержит ли строка, содержащая теги, разделенные пробелом, запятую или точку с запятой (или любой несловарный символ), данный тег?

Например:

Пример строки тега: tag tag_,tag_2;_tag test_3

Проверка на tag должна возвращать true.
Проверка на test должна возвращать false, поскольку строка тега содержит test_3 not test.
Проверка на hello должна возвращать false.

Также регистр не должен иметь значения, но там я могу просто upper строка тега.Теги могут содержать только символ, цифру или знак подчеркивания.

Я пытался использовать некоторый шаблон регулярных выражений, но даже с помощью многих публикаций на stackoverlow я не могу заставить себя работать так, как я этого хочу.

Спасибо.

Ответы [ 6 ]

1 голос
/ 08 апреля 2011

Я думаю, просто добавив границы слов \b вокруг вашего тега, который вы хотите найти.Это гарантирует отсутствие символа слова до или после вашего тега.

Pattern.compile("\\b"+tag+"\\b");
1 голос
/ 08 апреля 2011

Я бы, вероятно, просто использовал Scanner в этом случае и объявил бы разделители. Это выглядело бы так:

public static void main(String[] args) {
    String sample = "tag tag_,tag_2;_tag test_3";
    System.out.println("tag = " + containsTag(sample, "tag"));
    System.out.println("test = " + containsTag(sample, "test"));
    System.out.println("hello = " + containsTag(sample, "hello"));
}

public static boolean containsTag(String text, String tag) {
    Scanner scanner = new Scanner(text).useDelimiter(" |,|;");
    while (scanner.hasNext()) {
        if (scanner.next().equalsIgnoreCase(tag)) {
            return true;
        }
    }
    return false;
}

Если вы требуете, чтобы теги могли быть разделены чем-либо, кроме символов, цифр и подчеркиваний, вы можете просто использовать "[^A-Za-z0-9_]" в качестве разделителя вместо " |,|;".

0 голосов
/ 08 апреля 2011

Спасибо всем!

Вот тестовый пакет с некоторыми решениями для других:
Я думаю, что я использую метод hasTag2, но, похоже, он не имеет большого значения ..

public class TagTest extends TestCase {
private TagContainer tc = new TagContainer("tag tag_,tag_2;_tag test_3");

public void testHasTag() {
    test(true, "tag", "tag_", "tag_2", "_tag", "test_3", "TAG", "TEST_3", "TAG_");
    test(false, "test", "_ta", "hello");
}

private void test(boolean result, String... tags) {
    for (String tag : tags) {
        assertEquals(result, tc.hasTag1(tag));
        assertEquals(result, tc.hasTag2(tag));
        assertEquals(result, tc.hasTag3(tag));
        assertEquals(result, tc.hasTag4(tag));
    }
}

class TagContainer {
    private String tagData;

    public TagContainer(String t) {
        this.tagData = t;
    }

    public boolean hasTag1(String tag) {
        String delimeters = " ,;"; // Valid delimiter chars
        Pattern p = Pattern.compile("[" + delimeters + "]" + tag.toLowerCase() + "[" + delimeters + "]");
        Matcher m = p.matcher(" " + tagData.toLowerCase() + " ");
        return m.find();
    }

    public boolean hasTag2(String tag) {
        String[] tags = tagData.toLowerCase().split("[\\s,;]+");
        List<String> listOfTags = Arrays.asList(tags);
        return listOfTags.contains(tag.toLowerCase());
    }

    public boolean hasTag3(String tag) {
        Scanner scanner = new Scanner(tagData.toLowerCase()).useDelimiter(" |,|;");
        while (scanner.hasNext()) {
            if (scanner.next().equals(tag.toLowerCase())) {
                return true;
            }
        }
        return false;
    }

    public boolean hasTag4(String tag) {
        String[] tests = tagData.toLowerCase().split(" |,|;");
        Set<String> tags = new HashSet<String>();
        Collections.addAll(tags, tests);
        return tags.contains(tag.toLowerCase());
    }
}

}
Спасибо!

0 голосов
/ 08 апреля 2011

Это работает для меня, но не учитывает несколько вещей, объяснение и улучшение см. Ниже:

 String s = "tag tag_,tag_2;_tag test_3";

 String val = "tag";     
 Matcher m = Pattern.compile(val+"\\W").matcher(s);
 System.out.println(m.find());

 val = "test";
 m = Pattern.compile(val+"\\W").matcher(s);
 System.out.println(m.find());

 val = "hello";
 m = Pattern.compile(val+"\\W").matcher(s);
 System.out.println(m.find());

Мой вывод:

true
false
false

ПРИМЕЧАНИЕ : если вам нужны такие значения, как "_tag;" чтобы вернуть false, вы также должны добавить «\ W» в начало шаблона, это может вызвать проблему, хотя с соответствием для начала строки, поэтому вам нужно использовать специальные | и ^ символы, подобные так, и в этом отношении вы также можете захотеть сделать то же самое и в конце строки, используя | и $: Pattern.compile("(^|\\W)"+val+"(\\W|$)").matcher(s)

  • (^|\\W) = соответствует началу строки, ИЛИ несловесный символ
  • val = слово для соответствия
  • (\\W|$) = соответствует несловесный символ ИЛИ конец сама линия

Это будет соответствовать словам в середине или начале или конце строки.

0 голосов
/ 08 апреля 2011

Здесь есть несколько возможных подходов. Один из способов - разделить строку с помощью регулярного выражения, соответствующего пробелам, запятым или символам табуляции, и сравнить токены разделения ...

String[] tags = stringFullOfTags.split("[\\s,;]+");

Регулярное выражение [\ s,;] + будет соответствовать одному или нескольким пробелам (\ s - обратите внимание на двойное экранирование специального символа \ s регулярного выражения), точку с запятой или запятую. Метод String split возвращает массив токенов (в данном случае тегов), разделенных значениями, разделенными токенами, соответствующими регулярному выражению. Поэтому массив тегов должен содержать все элементы tag *.

Теперь, чтобы проверить наличие определенных элементов тега, преобразуйте массив в список и используйте удобные методы интерфейсов списка ...

List<String> listOfTags = Arrays.asList(tags);
if (listOfTags.contains("tag") {
    ....
} else if (listOfTags.containsAll(Arrays.asList({"tag", "test_3"})) {
    ....
}
0 голосов
/ 08 апреля 2011

С регулярным выражением и небольшим количеством обмана - но это облегчает регулярное выражение:

String test = "tag tag_,tag_2;_tag test_3";
String tag  = "tag";
String delim = " ,;";    // those are your valid delimiter chars


Pattern p = Pattern.compile("[" + delim + "]" + tag + "[" + delim + "]");
Matcher m = p.matcher(" " + test.toLowerCase() + " ");
System.out.println(m.find());

(я только добавил пробел в начале и в конце;))

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