代码之家  ›  专栏  ›  技术社区  ›  Aaron

如何在Java中以字符串不敏感的方式检查字符串是否包含另一个字符串?

  •  332
  • Aaron  · 技术社区  · 16 年前

    假设我有两条线,

    String s1 = "AbBaCca";
    String s2 = "bac";
    

    我想退票 s2 包含在 s1 . 我可以这样做:

    return s1.contains(s2);
    

    我很确定 contains() 是区分大小写的,但是我不能通过阅读文档来确定这一点。如果是这样,我想我最好的方法是:

    return s1.toLowerCase().contains(s2.toLowerCase());
    

    除此之外,是否还有其他(可能更好)方法可以在不考虑案件敏感性的情况下实现这一点?

    17 回复  |  直到 16 年前
        1
  •  290
  •   Mike Omeiri Kouider    6 年前

    Pattern.compile(Pattern.quote(wantedStr), Pattern.CASE_INSENSITIVE).matcher(source).find();
    

        2
  •  239
  •   Community CDub    7 年前

    the answer by Dave L. \d

    Pattern.compile(Pattern.quote(s2), Pattern.CASE_INSENSITIVE).matcher(s1).find();
    
        3
  •  128
  •   Peter Mortensen icecrime    9 年前

    org.apache.commons.lang3.StringUtils.containsIgnoreCase("AbBaCca", "bac");
    

    Apache Commons

        4
  •  102
  •   icza    8 年前

    String.regionMatches()

    toLowerCase()

    String.regionMatches() String ignoreCase

    public static boolean containsIgnoreCase(String src, String what) {
        final int length = what.length();
        if (length == 0)
            return true; // Empty string is contained
    
        final char firstLo = Character.toLowerCase(what.charAt(0));
        final char firstUp = Character.toUpperCase(what.charAt(0));
    
        for (int i = src.length() - length; i >= 0; i--) {
            // Quick check before calling the more expensive regionMatches() method:
            final char ch = src.charAt(i);
            if (ch != firstLo && ch != firstUp)
                continue;
    
            if (src.regionMatches(true, i, what, 0, length))
                return true;
        }
    
        return false;
    }
    

    1. String.contains()
    2. Pattern.compile().matcher().find()
    3. Pattern

                                                RELATIVE SPEED   1/RELATIVE SPEED
     METHOD                          EXEC TIME    TO SLOWEST      TO FASTEST (#1)
    ------------------------------------------------------------------------------
     1. Using regionMatches()          670 ms       10.7x            1.0x
     2. 2x lowercase+contains         2829 ms        2.5x            4.2x
     3. 1x lowercase+contains cache   2446 ms        2.9x            3.7x
     4. Regexp                        7180 ms        1.0x           10.7x
     5. Regexp+cached pattern         1845 ms        3.9x            2.8x
    

    contains()


    import java.util.regex.Pattern;
    
    public class ContainsAnalysis {
    
        // Case 1 utilizing String.regionMatches()
        public static boolean containsIgnoreCase(String src, String what) {
            final int length = what.length();
            if (length == 0)
                return true; // Empty string is contained
    
            final char firstLo = Character.toLowerCase(what.charAt(0));
            final char firstUp = Character.toUpperCase(what.charAt(0));
    
            for (int i = src.length() - length; i >= 0; i--) {
                // Quick check before calling the more expensive regionMatches()
                // method:
                final char ch = src.charAt(i);
                if (ch != firstLo && ch != firstUp)
                    continue;
    
                if (src.regionMatches(true, i, what, 0, length))
                    return true;
            }
    
            return false;
        }
    
        // Case 2 with 2x toLowerCase() and contains()
        public static boolean containsConverting(String src, String what) {
            return src.toLowerCase().contains(what.toLowerCase());
        }
    
        // The cached substring for case 3
        private static final String S = "i am".toLowerCase();
    
        // Case 3 with pre-cached substring and 1x toLowerCase() and contains()
        public static boolean containsConverting(String src) {
            return src.toLowerCase().contains(S);
        }
    
        // Case 4 with regexp
        public static boolean containsIgnoreCaseRegexp(String src, String what) {
            return Pattern.compile(Pattern.quote(what), Pattern.CASE_INSENSITIVE)
                        .matcher(src).find();
        }
    
        // The cached pattern for case 5
        private static final Pattern P = Pattern.compile(
                Pattern.quote("i am"), Pattern.CASE_INSENSITIVE);
    
        // Case 5 with pre-cached Pattern
        public static boolean containsIgnoreCaseRegexp(String src) {
            return P.matcher(src).find();
        }
    
        // Main method: perfroms speed analysis on different contains methods
        // (case ignored)
        public static void main(String[] args) throws Exception {
            final String src = "Hi, I am Adam";
            final String what = "i am";
    
            long start, end;
            final int N = 10_000_000;
    
            start = System.nanoTime();
            for (int i = 0; i < N; i++)
                containsIgnoreCase(src, what);
            end = System.nanoTime();
            System.out.println("Case 1 took " + ((end - start) / 1000000) + "ms");
    
            start = System.nanoTime();
            for (int i = 0; i < N; i++)
                containsConverting(src, what);
            end = System.nanoTime();
            System.out.println("Case 2 took " + ((end - start) / 1000000) + "ms");
    
            start = System.nanoTime();
            for (int i = 0; i < N; i++)
                containsConverting(src);
            end = System.nanoTime();
            System.out.println("Case 3 took " + ((end - start) / 1000000) + "ms");
    
            start = System.nanoTime();
            for (int i = 0; i < N; i++)
                containsIgnoreCaseRegexp(src, what);
            end = System.nanoTime();
            System.out.println("Case 4 took " + ((end - start) / 1000000) + "ms");
    
            start = System.nanoTime();
            for (int i = 0; i < N; i++)
                containsIgnoreCaseRegexp(src);
            end = System.nanoTime();
            System.out.println("Case 5 took " + ((end - start) / 1000000) + "ms");
        }
    
    }
    
        5
  •  17
  •   user299791    8 年前

    String s1 = "abBaCca";
    String s2 = "bac";
    
    String s1Lower = s1;
    
    //s1Lower is exact same string, now convert it to lowercase, I left the s1 intact for print purposes if needed
    
    s1Lower = s1Lower.toLowerCase();
    
    String trueStatement = "FALSE!";
    if (s1Lower.contains(s2)) {
    
        //THIS statement will be TRUE
        trueStatement = "TRUE!"
    }
    
    return trueStatement;
    

        6
  •  15
  •   Phil    13 年前

    String

    String foobar = "fooBar";
    String bar = "FOO";
    if (foobar.toLowerCase().contains(bar.toLowerCase()) {
        System.out.println("It's a match!");
    }
    
        7
  •  6
  •   Peter Mortensen icecrime    9 年前

    regular expressions

    boolean found = s1.matches("(?i).*" + s2+ ".*");
    
        8
  •  3
  •   Hakanai    10 年前

    public static boolean containsIgnoreCase(String haystack, String needle) {
        return indexOfIgnoreCase(haystack, needle) >= 0;
    }
    
    public static int indexOfIgnoreCase(String haystack, String needle) {
        StringSearch stringSearch = new StringSearch(needle, haystack);
        stringSearch.getCollator().setStrength(Collator.PRIMARY);
        return stringSearch.first();
    }
    
        9
  •  3
  •   Peter Mortensen icecrime    9 年前

    1. for (SongInformation song: songs) {
          if (song.artist.toLowerCase().indexOf(pattern.toLowercase() > -1) {
                  ...
          }
      }
      
    2. for (SongInformation song: songs) {
          if (song.artist.matches("(?i).*" + pattern + ".*")) {
          ...
          }
      }
      
    3. Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
      Matcher m = p.matcher("");
      for (SongInformation song: songs) {
          m.reset(song.artist);
          if (m.find()) {
          ...
          }
      }
      

        10
  •  1
  •   SCdF    16 年前

        11
  •  0
  •   Peter Mortensen icecrime    9 年前
    String container = " Case SeNsitive ";
    String sub = "sen";
    if (rcontains(container, sub)) {
        System.out.println("no case");
    }
    
    public static Boolean rcontains(String container, String sub) {
    
        Boolean b = false;
        for (int a = 0; a < container.length() - sub.length() + 1; a++) {
            //System.out.println(sub + " to " + container.substring(a, a+sub.length()));
            if (sub.equalsIgnoreCase(container.substring(a, a + sub.length()))) {
                b = true;
            }
        }
        return b;
    }
    

    for

    equalsIgnoreCase

        12
  •  0
  •   Peter Mortensen icecrime    9 年前

    URL

    public static String lowerCaseAscii(String s) {
        if (s == null)
            return null;
    
        int len = s.length();
        char[] buf = new char[len];
        s.getChars(0, len, buf, 0);
        for (int i=0; i<len; i++) {
            if (buf[i] >= 'A' && buf[i] <= 'Z')
                buf[i] += 0x20;
        }
    
        return new String(buf);
    }
    
    public static boolean containsIgnoreCaseAscii(String str, String searchStr) {
        return StringUtils.contains(lowerCaseAscii(str), lowerCaseAscii(searchStr));
    }
    
        13
  •  0
  •   Stéphane GRILLON    8 年前
    import java.text.Normalizer;
    
    import org.apache.commons.lang3.StringUtils;
    
    public class ContainsIgnoreCase {
    
        public static void main(String[] args) {
    
            String in = "   Annulée ";
            String key = "annulee";
    
            // 100% java
            if (Normalizer.normalize(in, Normalizer.Form.NFD).replaceAll("[\\p{InCombiningDiacriticalMarks}]", "").toLowerCase().contains(key)) {
                System.out.println("OK");
            } else {
                System.out.println("KO");
            }
    
            // use commons.lang lib
            if (StringUtils.containsIgnoreCase(Normalizer.normalize(in, Normalizer.Form.NFD).replaceAll("[\\p{InCombiningDiacriticalMarks}]", ""), key)) {
                System.out.println("OK");
            } else {
                System.out.println("KO");
            }
    
        }
    
    }
    
        14
  •  -1
  •   Jainendra    12 年前
    String x="abCd";
    System.out.println(Pattern.compile("c",Pattern.CASE_INSENSITIVE).matcher(x).find());
    
        15
  •  -1
  •   Tunaki    9 年前

    String s1 = "AbBaCca";
    String s2 = "bac";
    String toLower = s1.toLowerCase();
    return toLower.contains(s2);
    
        16
  •  -1
  •   Ataur Rahman Munna    7 年前
    "AbCd".toLowerCase().contains("abcD".toLowerCase())
    
        17
  •  -2
  •   rainer    7 年前

      String str = new String("Welcome");
      System.out.print("Found Index :" );
      System.out.println(str.indexOf( 'o' ));