如何检查字符串是否包含“tags”由任何非单词标记分隔包含 Java 中的给定标记

发布于 2024-10-30 18:43:27 字数 428 浏览 5 评论 0原文

有人知道如何在 Java 中检查包含由空格、逗号或分号(或任何非单词字符)分隔的标签的字符串是否包含给定标签吗?

例如:

示例标记字符串:tag tag_,tag_2;_tag test_3

检查 tag 应返回 true。
检查 test 应返回 false,因为标记字符串包含 test_3 而不是 test
检查 hello 应返回 false。

另外,大小写并不重要,但我可以将标签字符串放在上面。标签只能包含字符、数字或下划线。

我试图使用一些正则表达式模式,但是,即使在 stackoverlow 上许多帖子的帮助下,我也无法让我按照我想要的方式工作。

谢谢。

Does someone know a way on how to check, in Java, if a string containing tags seperated by space, comma or semicolon (or any non-word character) contains a given tag?

For example:

Sample tag string: tag tag_,tag_2;_tag test_3

Check for tag should return true.
Check for test should return false because it the tag string contains test_3 not test.
Check for hello should return false.

Also case shouldn't matter but there i could just upper the tag string. The tags may contain only character, digit or underscore.

I was trying to use some regex pattern but, even with the help of many post on stackoverlow, i cannot get i to work as i want it.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

任谁 2024-11-06 18:43:27

在这种情况下,我可能只使用 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_]" 作为分隔符而不是 " |,|;"

I'd probably just use a Scanner in this case and declare the delimiters. It'd look like this:

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;
}

If your requirement is that tags can be delimited by anything other than characters, digits and underscores you could just use "[^A-Za-z0-9_]" as the delimiter instead of " |,|;".

氛圍 2024-11-06 18:43:27

我认为只需在您想要搜索的标签周围添加单词边界 \b 即可。这可以确保标签之前或之后没有单词字符。

Pattern.compile("\\b"+tag+"\\b");

I think just adding word boundaries \b around your tag, that you want to search. This assures, that there is no word character before or after your tag.

Pattern.compile("\\b"+tag+"\\b");
七秒鱼° 2024-11-06 18:43:27

这里有几种可能的方法。一种方法是使用匹配空格、逗号或制表符的正则表达式来拆分字符串,然后比较拆分标记...

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"})) {
    ....
}

There's a couple of possible approaches here. One way is to split the String using a regular expression that matches on whitespace, commas or tabs then compare the split tokens...

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

The regular expression [\s,;]+ will match one or more spaces (\s - note the double escaping of the regular expression special character \s), semicolons or commas. The String split method will return the array of tokens (in this case tags) separated by values split by tokens matching the regular expression. The tags array should therefore contain all the tag* elements.

Now to check for certain tag elements convert the array to a List and use the List interfaces convenience methods...

List<String> listOfTags = Arrays.asList(tags);
if (listOfTags.contains("tag") {
    ....
} else if (listOfTags.containsAll(Arrays.asList({"tag", "test_3"})) {
    ....
}
ㄟ。诗瑗 2024-11-06 18:43:27

使用正则表达式和一点作弊 - 但它使正则表达式变得简单:(

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());

我只是在开头和结尾添加了一个空格;))

With regex and a little bit of cheating - but it keeps the regexp easy:

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());

(I just added a space at the beginning and at the end ;) )

晒暮凉 2024-11-06 18:43:27

这对我有用,但它没有考虑到几个因素,请参阅下面的解释和改进:

 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) = 匹配行开头,
    OR 非单词字符
  • val =
    匹配的单词
  • (\\W|$) = 匹配 a
    非单词字符OR结尾
    行本身

将匹配行中间、开头或结尾的单词。

This works for me, but it does not take several things into account, see below for explanation and improvement:

 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());

My output is:

true
false
false

NOTE: if you want values like "_tag;" to return false, you have to add the "\W" to the beginning of the pattern too, this can cause an issue though with matching for the start of the line, so you need to use the special | and ^ chars like so, and for that matter you may also want to the same thing to the line ending too, using | and $:
Pattern.compile("(^|\\W)"+val+"(\\W|$)").matcher(s)

  • (^|\\W) = match the line beginning,
    OR a non-word character
  • val = the
    word to match
  • (\\W|$) = match a
    non-word character OR the end of the
    line itself

That will match words in the middle or start or end of the line.

一绘本一梦想 2024-11-06 18:43:27

谢谢大家!

这是一个 junit 测试,其中包含其他人的一些解决方案:
我想我会选择 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());
    }
}

}
谢谢!

Thanks everyone!

Here's a junit test with some of the solutions for other's:
I think i go for hasTag2 method but it doesn't seem to matter much..

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());
    }
}

}
Thanks!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文