क्या इंडेक्सऑफ (स्ट्रिंग) विधि मामला संवेदनशील है? यदि हां, तो क्या इसका कोई मामला असंवेदनशील संस्करण है?
क्या इंडेक्सऑफ (स्ट्रिंग) विधि मामला संवेदनशील है? यदि हां, तो क्या इसका कोई मामला असंवेदनशील संस्करण है?
जवाबों:
indexOf()
तरीकों सभी केस-संवेदी होते। आप उन्हें (मोटे तौर पर, टूटे-फूटे तरीके से, लेकिन बहुत से मामलों के लिए काम कर सकते हैं) केस-असंवेदनशील अपने तार को ऊपरी / निचले मामले में पहले से परिवर्तित कर सकते हैं:
s1 = s1.toLowerCase(Locale.US);
s2 = s2.toLowerCase(Locale.US);
s1.indexOf(s2);
"ß".toUpperCase().equals("SS")
क्या इंडेक्सऑफ (स्ट्रिंग) विधि मामला संवेदनशील है?
हां, यह संवेदनशील है:
@Test
public void indexOfIsCaseSensitive() {
assertTrue("Hello World!".indexOf("Hello") != -1);
assertTrue("Hello World!".indexOf("hello") == -1);
}
यदि हां, तो क्या इसका कोई मामला असंवेदनशील संस्करण है?
नहीं, वहाँ नहीं है। IndexOf पर कॉल करने से पहले आप दोनों स्ट्रिंग्स को लोअर केस में बदल सकते हैं:
@Test
public void caseInsensitiveIndexOf() {
assertTrue("Hello World!".toLowerCase().indexOf("Hello".toLowerCase()) != -1);
assertTrue("Hello World!".toLowerCase().indexOf("hello".toLowerCase()) != -1);
}
"ı".toLowerCase(Locale.US).indexOf("I".toLowerCase(Locale.US))
0 वापस आ जाना चाहिए क्योंकि पहला स्ट्रिंग एक तुर्की निचला मामला है "I"
, और इसलिए "I"
दूसरे में ऊपरी-मामले के बराबर तुलना करना चाहिए , लेकिन रिटर्न -1 क्योंकि बाद को "i"
इसके बजाय बदल दिया जाता है)।
अपाचे कॉमन्स लैंग लाइब्रेरी के स्ट्रिंगरटिल्स वर्ग में एक अनदेखी मामला विधि है
indexOfIgnoreCase (CharSequence str, CharSequence searchStr)
हाँ, indexOf
मामला संवेदनशील है।
केस असंवेदनशीलता के लिए सबसे अच्छा तरीका मुझे मिला है:
String original;
int idx = original.toLowerCase().indexOf(someStr.toLowerCase());
जो असंवेदनशील मामला करेगा indexOf()
।
original.toLowerCase().length()
हमेशा बराबर नहीं होता है original.length()
। परिणाम idx
सही तरीके से वापस मैप करने में सक्षम नहीं है original
।
यहां मेरा समाधान है जो किसी भी ढेर मेमोरी को आवंटित नहीं करता है, इसलिए यह यहां उल्लिखित अन्य कार्यान्वयनों की तुलना में काफी तेज होना चाहिए।
public static int indexOfIgnoreCase(final String haystack,
final String needle) {
if (needle.isEmpty() || haystack.isEmpty()) {
// Fallback to legacy behavior.
return haystack.indexOf(needle);
}
for (int i = 0; i < haystack.length(); ++i) {
// Early out, if possible.
if (i + needle.length() > haystack.length()) {
return -1;
}
// Attempt to match substring starting at position i of haystack.
int j = 0;
int ii = i;
while (ii < haystack.length() && j < needle.length()) {
char c = Character.toLowerCase(haystack.charAt(ii));
char c2 = Character.toLowerCase(needle.charAt(j));
if (c != c2) {
break;
}
j++;
ii++;
}
// Walked all the way to the end of the needle, return the start
// position that this was found.
if (j == needle.length()) {
return i;
}
}
return -1;
}
और यहां इकाई परीक्षण हैं जो सही व्यवहार को सत्यापित करते हैं।
@Test
public void testIndexOfIgnoreCase() {
assertThat(StringUtils.indexOfIgnoreCase("A", "A"), is(0));
assertThat(StringUtils.indexOfIgnoreCase("a", "A"), is(0));
assertThat(StringUtils.indexOfIgnoreCase("A", "a"), is(0));
assertThat(StringUtils.indexOfIgnoreCase("a", "a"), is(0));
assertThat(StringUtils.indexOfIgnoreCase("a", "ba"), is(-1));
assertThat(StringUtils.indexOfIgnoreCase("ba", "a"), is(1));
assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", " Royal Blue"), is(-1));
assertThat(StringUtils.indexOfIgnoreCase(" Royal Blue", "Royal Blue"), is(1));
assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", "royal"), is(0));
assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", "oyal"), is(1));
assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", "al"), is(3));
assertThat(StringUtils.indexOfIgnoreCase("", "royal"), is(-1));
assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", ""), is(0));
assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", "BLUE"), is(6));
assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", "BIGLONGSTRING"), is(-1));
assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", "Royal Blue LONGSTRING"), is(-1));
}
assertThat(StringUtils.indexOfIgnoreCase("ı" /* Turkish lower-case I, U+0131 */, "I"), is(0));
हां, यह केस-संवेदी है। खोज करने से पहले आप indexOf
अपने स्ट्रिंग और स्ट्रिंग पैरामीटर को ऊपरी-मामले में परिवर्तित करके एक केस-असंवेदनशील कर सकते हैं ।
String str = "Hello world";
String search = "hello";
str.toUpperCase().indexOf(search.toUpperCase());
ध्यान दें कि टॉपर कैस कुछ परिस्थितियों में काम नहीं कर सकता है। उदाहरण के लिए यह:
String str = "Feldbergstraße 23, Mainz";
String find = "mainz";
int idxU = str.toUpperCase().indexOf (find.toUpperCase ());
int idxL = str.toLowerCase().indexOf (find.toLowerCase ());
idxU 20 होगा, जो गलत है! idxL 19 होगा, जो सही है। समस्या का कारण क्या है थ्यूपरकैस () "into" चरित्र को TWO वर्णों में परिवर्तित करता है, "SS" और यह अनुक्रमणिका को बंद कर देता है।
नतीजतन, हमेशा toLowerCase () के साथ रहें
find
करते हैं "STRASSE"
, तो यह लोअर केस वेरिएंट में बिल्कुल नहीं मिलता है, लेकिन ऊपरी केस वर्जन में इसे सही तरीके से ढूंढता है।
एक बार वापस आने के बाद आप सूचकांक मूल्य के साथ क्या कर रहे हैं?
यदि आप इसे अपनी स्ट्रिंग में हेरफेर करने के लिए उपयोग कर रहे हैं, तो क्या आप इसके बजाय एक नियमित अभिव्यक्ति का उपयोग नहीं कर सकते हैं?
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class StringIndexOfRegexpTest {
@Test
public void testNastyIndexOfBasedReplace() {
final String source = "Hello World";
final int index = source.toLowerCase().indexOf("hello".toLowerCase());
final String target = "Hi".concat(source.substring(index
+ "hello".length(), source.length()));
assertEquals("Hi World", target);
}
@Test
public void testSimpleRegexpBasedReplace() {
final String source = "Hello World";
final String target = source.replaceFirst("(?i)hello", "Hi");
assertEquals("Hi World", target);
}
}
@Test
public void testIndexofCaseSensitive() {
TestCase.assertEquals(-1, "abcDef".indexOf("d") );
}
एक ही समस्या थी। मैंने नियमित अभिव्यक्ति और अपाचे StringUtils.indexOfIgnoreCase-Method की कोशिश की, लेकिन दोनों बहुत धीमे थे ... इसलिए मैंने खुद एक छोटा तरीका लिखा ...:
public static int indexOfIgnoreCase(final String chkstr, final String searchStr, int i) {
if (chkstr != null && searchStr != null && i > -1) {
int serchStrLength = searchStr.length();
char[] searchCharLc = new char[serchStrLength];
char[] searchCharUc = new char[serchStrLength];
searchStr.toUpperCase().getChars(0, serchStrLength, searchCharUc, 0);
searchStr.toLowerCase().getChars(0, serchStrLength, searchCharLc, 0);
int j = 0;
for (int checkStrLength = chkstr.length(); i < checkStrLength; i++) {
char charAt = chkstr.charAt(i);
if (charAt == searchCharLc[j] || charAt == searchCharUc[j]) {
if (++j == serchStrLength) {
return i - j + 1;
}
} else { // faster than: else if (j != 0) {
i = i - j;
j = 0;
}
}
}
return -1;
}
मेरे परीक्षणों के अनुसार इसकी गति बहुत तेज़ है ... (कम से कम अगर आपकी सर्चस्ट्रीमिंग कम बल्कि) है। यदि आपके पास सुधार या बग के लिए कोई सुझाव है तो मुझे बताना अच्छा होगा ... (जब से मैं एक कोड में इस कोड का उपयोग करता हूं;;)
indexOfIgnoreCase("İ","i")
0 लौटना चाहिए क्योंकि तुर्की पाठ İ
के i
लिए सही पूंजीकरण है , लेकिन इसके बजाय रिटर्न -1 क्योंकि i
अधिक सामान्य के लिए पूंजीकृत है I
)।
पहले सवाल का जवाब कई बार दिया जा चुका है। हाँString.indexOf()
विधियां सभी मामले के प्रति संवेदनशील हैं।
यदि आपको एक स्थानीय-संवेदनशील की आवश्यकता है तो आप Collator काindexOf()
उपयोग कर सकते हैं । आपके द्वारा निर्धारित शक्ति मान के आधार पर, आप मामले की असंवेदनशील तुलना प्राप्त कर सकते हैं, और उच्चारण अक्षरों को भी गैर-उच्चारण वाले लोगों के समान मान सकते हैं, आदि यहाँ एक उदाहरण है कि यह कैसे करें:
private int indexOf(String original, String search) {
Collator collator = Collator.getInstance();
collator.setStrength(Collator.PRIMARY);
for (int i = 0; i <= original.length() - search.length(); i++) {
if (collator.equals(search, original.substring(i, i + search.length()))) {
return i;
}
}
return -1;
}
लेकिन एक लिखना मुश्किल नहीं है:
public class CaseInsensitiveIndexOfTest extends TestCase {
public void testOne() throws Exception {
assertEquals(2, caseInsensitiveIndexOf("ABC", "xxabcdef"));
}
public static int caseInsensitiveIndexOf(String substring, String string) {
return string.toLowerCase().indexOf(substring.toLowerCase());
}
}
"ı"
एक लोअर-केस वैरिएंट है (बस सबसे अधिक लंबू में डिफ़ॉल्ट नहीं है) "I"
। या वैकल्पिक रूप से, के लिए कोई स्थान जहां के लिए एक मशीन समूह पर चलने अगर "ı"
है डिफ़ॉल्ट, यह सूचना है कि करने के लिए असफल हो जायेगी "i"
भी की एक लोअर केस संस्करण है "I"
।
static string Search(string factMessage, string b)
{
int index = factMessage.IndexOf(b, StringComparison.CurrentCultureIgnoreCase);
string line = null;
int i = index;
if (i == -1)
{ return "not matched"; }
else
{
while (factMessage[i] != ' ')
{
line = line + factMessage[i];
i++;
}
return line;
}
}
यहां अपाचे के स्ट्रिंगटाइल संस्करण जैसा दिखने वाला एक संस्करण है:
public int indexOfIgnoreCase(String str, String searchStr) {
return indexOfIgnoreCase(str, searchStr, 0);
}
public int indexOfIgnoreCase(String str, String searchStr, int fromIndex) {
// /programming/14018478/string-contains-ignore-case/14018511
if(str == null || searchStr == null) return -1;
if (searchStr.length() == 0) return fromIndex; // empty string found; use same behavior as Apache StringUtils
final int endLimit = str.length() - searchStr.length() + 1;
for (int i = fromIndex; i < endLimit; i++) {
if (str.regionMatches(true, i, searchStr, 0, searchStr.length())) return i;
}
return -1;
}
मैं वन के लिए दावा करना चाहता हूं और केवल समाधान अब तक पोस्ट किया गया है जो वास्तव में काम करता है। :-)
समस्याओं का तीन वर्गों से सामना करना पड़ता है।
निचले और अपरकेस के लिए गैर-संक्रमणीय मिलान नियम। अन्य उत्तरों में तुर्की I समस्या का अक्सर उल्लेख किया गया है। String.regionMatches के लिए एंड्रॉइड स्रोत में टिप्पणियों के अनुसार, केस-असंवेदनशील समानता के लिए तुलना करते हुए जॉर्जियाई तुलना नियमों को निचले-मामले में अतिरिक्त रूपांतरण की आवश्यकता होती है।
ऐसे मामले जहां ऊपरी और निचले मामले में अक्षरों की एक अलग संख्या होती है। बहुत सारे समाधान अब तक इन मामलों में विफल रहे हैं। उदाहरण: जर्मन STRASSE बनाम स्ट्रैस में केस-असंवेदनशील समानता है, लेकिन अलग-अलग लंबाई है।
उच्चारण पात्रों की मजबूती। लोकेल और संदर्भ प्रभाव, उच्चारण मेल खाता है या नहीं। फ्रेंच में, 'é' का अपरकेस फॉर्म 'E' है, हालांकि अपरकेस एक्सेंट का उपयोग करने की दिशा में एक आंदोलन है। कनाडाई फ्रांसीसी में, बिना अपवाद के 'é' का ऊपरी-मामला रूप ',' है। खोज करते समय दोनों देशों के उपयोगकर्ता "ई" से "ई" से मिलान करने की अपेक्षा करेंगे। क्या उच्चारण और अस्वीकार्य चरित्र मैच स्थानीय-विशिष्ट हैं। अब विचार करें: क्या "ई" समान "E" है? हाँ। ऐसा होता है। फ्रांसीसी स्थानों में, वैसे भी।
मैं वर्तमान में उपयोग कर रहा हूं android.icu.text.StringSearch
में केस-असंवेदनशील इंडेक्सऑफ संचालन के पिछले कार्यान्वयन को सही ढंग से लागू करने के लिए ।
गैर-एंड्रॉइड उपयोगकर्ता आईसीयू 4 जे पैकेज के माध्यम से समान कार्यक्षमता का उपयोग कर सकते हैं com.ibm.icu.text.StringSearch
कक्षा ।
एंड्रॉइड के रूप में सही आईसीयू पैकेज ( android.icu.text
या com.ibm.icu.text
) में संदर्भ कक्षाओं के लिए सावधान रहें और जेआरई दोनों के पास अन्य नामस्थानों (जैसे Collator) में एक ही नाम के साथ कक्षाएं हैं।
this.collator = (RuleBasedCollator)Collator.getInstance(locale);
this.collator.setStrength(Collator.PRIMARY);
....
StringSearch search = new StringSearch(
pattern,
new StringCharacterIterator(targetText),
collator);
int index = search.first();
if (index != SearchString.DONE)
{
// remember that the match length may NOT equal the pattern length.
length = search.getMatchLength();
....
}
परीक्षण मामले (स्थान, पैटर्न, लक्ष्य पाठ, अपेक्षित। परिणाम):
testMatch(Locale.US,"AbCde","aBcDe",true);
testMatch(Locale.US,"éèê","EEE",true);
testMatch(Locale.GERMAN,"STRASSE","Straße",true);
testMatch(Locale.FRENCH,"éèê","EEE",true);
testMatch(Locale.FRENCH,"EEE","éèê",true);
testMatch(Locale.FRENCH,"éèê","ÉÈÊ",true);
testMatch(new Locale("tr-TR"),"TITLE","tıtle",true); // Turkish dotless I/i
testMatch(new Locale("tr-TR"),"TİTLE","title",true); // Turkish dotted I/i
testMatch(new Locale("tr-TR"),"TITLE","title",false); // Dotless-I != dotted i.
PS: जब तक मैं यह निर्धारित कर सकता हूं कि सबसे अच्छा, PRIMARY बाइंडिंग स्ट्रेंथ को सही काम करना चाहिए जब शब्दकोश नियमों के अनुसार स्थानीय-विशिष्ट नियम उच्चारण और गैर-उच्चारण वर्णों के बीच अंतर करते हैं; लेकिन मैं इस आधार का परीक्षण करने के लिए किस लोकेल का उपयोग नहीं करता हूं। दान किए गए परीक्षण मामलों की सराहना की जाएगी।
indexOf केस संवेदी है। ऐसा इसलिए है क्योंकि यह सूची में तत्वों की तुलना करने के लिए समान पद्धति का उपयोग करता है। एक ही चीज़ में सम्मिलित और हटाना है।