2011-04-07 67 views
0

给定的标签是否有人知道如何检查,在Java中的一种方式,如果包含标记的字符串由空格,逗号或分隔分号(或任何非单词字符)包含给定的标签?如何检查是否含有任何无字标记分隔的“标签”字符串包含在Java中

例如:

的示例代码字符串:tag tag_,tag_2;_tag test_3

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

同样情况下不应该的问题,但有我可以upper标记字符串。标签可能只包含字符,数字或下划线。

我试图用一些正则表达式,但是,即使有许多岗位上stackoverlow的帮助下,我不能让我的工作,因为我想它。

谢谢。

+0

你试过了什么正则表达式? – Randy 2011-04-07 20:15:02

回答

0

有一对夫妇这里可能的方法。一种方法是使用了在空白,逗号或制表符然后比较分裂的令牌相匹配的正则表达式来分割字符串...

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

正则表达式[\ S,;] +将匹配一个或多个空间(\ s - 注意正则表达式特殊字符\ s的双重转义),分号或逗号。 String split方法将返回由符合正则表达式的标记分隔的值分隔的标记数组(在这种情况下为标记)。标签数组应该包含所有的标签*元素。

现在检查某些标记元素是否将数组转换为List并使用List interfaces便捷方法...

List<String> listOfTags = Arrays.asList(tags); 
if (listOfTags.contains("tag") { 
    .... 
} else if (listOfTags.containsAll(Arrays.asList({"tag", "test_3"})) { 
    .... 
} 
1

我很可能只是用在这种情况下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

是否有你选择不使用正则表达式的原因?乍一看,这看起来效率显着不高。 – gnomed 2011-04-07 20:21:45

+0

使用正则表达式可以很好地覆盖所有情况,阅读起来通常比较复杂。 Plus正则表达式实际上并不像你想象的那样高效。如果您查看它所经历的代码,它必须编译一个模式,执行匹配并在流程中创建大量对象。请注意,'扫描仪'实际上是使用正则表达式进行分隔。所以这并不一定像它可能的那样高效,尽管我认为这并不重要,除非OP正在处理大量的这些问题。 – WhiteFang34 2011-04-07 20:25:39

+0

下面是一个从使用正则表达式分隔的扫描器到快50倍的特定代码的示例:http://stackoverflow.com/questions/5468396/java-insert-a-string-at-a-dynamic-index -position-which-index-is-a-a格式/ 5468636#5468636 – WhiteFang34 2011-04-07 20:28:50

0

用正则表达式和欺骗的一点 - 但它保持了正则表达式简单:

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

(我只是在开始和结束时增加了空间;))

0

这对我的作品,但它没有考虑几件事情考虑进去,见下面的解释和改进:

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 = word to matc ħ
  • (\\W|$) =匹配 非文字字符OR的 线本身的端

这将在中间匹配字或开始或行结束。

1

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

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

谢谢大家!

下面是一些其他的解决方案的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()); 
    } 
} 

}
谢谢!

相关问题