2011-04-07 61 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()); 
    } 
} 

}
謝謝!

相關問題