Replaces a char in a String

@param s
The input string
@param pos
The position of the char to be replaced
@param c
The new char
@return The new String
@see Source: http://www.rgagnon.com/javadetails/java-0030.html
327813
private static String replaceCharAt(String s, int pos, char c) {
		return s.substring(0, pos) + c + s.substring(pos + 1);
	}
1307671
public static String escape(CharSequence s) {
		StringBuilder str = new StringBuilder();
		int len = s.length();
		for (int i = 0; i < len; ++i) {
			char c = s.charAt(i);
			if (c == '&') str.append("&amp;");
			else if (c == '"') str.append("&quot;");
			else if (c == '\'') str.append("&apos;");
			else if (c == '>') str.append("&gt;");
			else if (c == '<') str.append("&lt;");
			else if (c < 32) str.append("&#").append((int)c).append(';');
			else str.append(c);
		}
		return str.toString();
	}
676283
public void putString(int pos, CharSequence s) {
		for (int i = 0; i < s.length(); ++i) {
			char c = s.charAt(i);
			byte b0 = (byte)c;
			byte b1 = (byte)(c >> 8);
			if (_order == ByteOrder.BIG_ENDIAN) {
				putBytes(pos, b1, b0);
			} else {
				putBytes(pos, b0, b1);
			}
			pos += 2;
		}
	}
860732
@Deprecated
	public static String removeChars(String S, char[] chars) {
		int pos;
		while((pos=indexOf(S, chars))!=-1) S=S.substring(0,pos)+S.substring(pos+1);
		return S;
	}
793129
public static final void c(String msg) {
        if (msg.replaceAll("\\s+", "").equals("")) {
            println(CONF_TEXT);
        } else {
            println(CONF_TEXT + ": " + msg);
        }
    }
46701
private static String scanForName(int pos, final char[] chars) {
      StringBuilder buf = new StringBuilder();
      while(pos < chars.length) {
         char ch = chars[pos++];
         switch(ch) {
            case ' ':
            case ']':
               return buf.toString();
            case '[':
            case '<':
            case '>':
            case '&':
            case '/':
               return "";
            default:
               if(ch < 0x20 || Character.isWhitespace(ch)) {
                  return "";
               } else {
                  buf.append(ch);
               }
         }
      }
      return "";
   }
1078225
public static String 
    trim( String string, int pos ) 
    {
        int len = string.length();

     	int leftPos = pos;
     	int rightPos = len;
     	
    	for( ; rightPos > 0; --rightPos ) 
    	{
    	    char ch = string.charAt( rightPos - 1 );
    		if( ch != ' '
    		    && ch != '\t' 
    		    && ch != '\n' 
    		    && ch != '\r' ) 
    		{    			
    			break;
    		}
    	}
    	
    	for( ; leftPos < rightPos; ++leftPos )
    	{
    	    char ch = string.charAt( leftPos ); 
    		if( ch != ' ' 
    		    && ch != '\t' 
    		    && ch != '\n' 
    		    && ch != '\r' ) 
    		{    			
    			break;
    		}
    	}
    	
    	if( rightPos <= leftPos ) 
    	{
    		return "";
    	}
    	
    	return ( leftPos == 0 && rightPos == string.length() )? string : 
    	                                                        string.substring( leftPos, rightPos );
    }
458922
protected final void putString(String s) {
        ensureCapacity(position + (s.length() * 2) + 1);

        System.arraycopy(s.getBytes(), 0, buffer, position, s.length());
        position += s.length();
        buffer[position++] = 0;
    }
70732
static void overwrite(StringBuffer sb, int pos, String s) {
        int len = s.length();
        for (int i = 0; i < len; i++) {
            sb.setCharAt(pos + i, s.charAt(i));
        }
    }
799521
@Override
    protected IWord nextLatinWord(int c, int pos) throws IOException
    {
        isb.clear();
        if ( c > 65280 ) c -= 65248;
        if ( c >= 65 && c <= 90 ) c += 32;
        isb.append((char)c);

        boolean _check = false, _wspace = false;
        ByteCharCounter counter = new ByteCharCounter();
        int ch, _ctype = 0, tcount = 1;             //number of different char type.
        int _TYPE  = StringUtil.getEnCharType(c);   //current char type.

        while ( (ch = readNext()) != -1 ) {
            //Covert the full-width char to half-width char.
            if ( ch > 65280 ) ch -= 65248;
            _ctype = StringUtil.getEnCharType(ch);
            if ( _ctype == StringUtil.EN_WHITESPACE ) {
                _wspace = true;
                break;
            }

            if ( _ctype == StringUtil.EN_PUNCTUATION ) {
                if ( ! StringUtil.isENKeepPunctuaton((char)ch) ) {
                    pushBack(ch);
                    break;
                }
                counter.increase((char)ch);
            }

            //Not EN_KNOW, and it could be letter, numeric.
            if ( _ctype == StringUtil.EN_UNKNOW ) {
                pushBack(ch);
                if ( StringUtil.isCJKChar( ch ) ) {
                    _check = true;
                }

                break;
            }

            //covert the lower case letter to upper case.
            if ( ch >= 65 && ch <= 90 ) ch += 32;
            if ( ch > 0 ) {
                isb.append((char)ch);
            }

            /* Char type counter.
             * condition to start the secondary segmentation.
             * @reader: we could do better.
             *
             * @added 2013-12-16
            */
            if ( _ctype != _TYPE ) {
                tcount++;
                _TYPE = _ctype;
            }

            if ( isb.length() > config.MAX_LATIN_LENGTH ) {
                break;
            }
        }

        /*
         * @added at 2016/11/24
         * clear the dot punctuation behind the string buffer
         * and recount the tcount as needed
        */
        int oLen = isb.length();
        for ( int i = oLen - 1; i > 0
                && StringUtil.isNoTailingPunctuation(isb.charAt(i)); i-- ) {
            pushBack(isb.charAt(i));
            isb.deleteCharAt(i);
            _check = false;
        }

        if ( oLen > isb.length()
                && ! StringUtil.isEnPunctuation(isb.last()) ) {
            tcount--;
        }



        IWord wd   = null;
        String str = isb.toString();
        String date = null;

        /*
         * special entity word check like email, URL, ip address
        */
        int colonNum = counter.get(':');
        int pointNum = counter.get('.');
        if ( counter.get('@') == 1 && pointNum > 0
                && EntityFormat.isMailAddress(str) ) {
            wd = new Word(str, IWord.T_BASIC_LATIN, Entity.E_EMAIL_A);
            wd.setPartSpeech(IWord.EN_POSPEECH);
            return wd;
        } else if ( tcount == 1 && StringUtil.isEnNumeric(isb.first())
                && EntityFormat.isMobileNumber(str) ) {
            wd = new Word(str, IWord.T_BASIC_LATIN, Entity.E_MOBILE_A);
            wd.setPartSpeech(IWord.NUMERIC_POSPEECH);
            return wd;
        } else if ( tcount == 7 && pointNum == 3
                && StringUtil.isEnNumeric(isb.first())
                && EntityFormat.isIpAddress(str) ) {
            wd = new Word(str, IWord.T_BASIC_LATIN, Entity.E_IP_A);
            wd.setPartSpeech(IWord.EN_POSPEECH);
            return wd;
        } else if ( pointNum > 0 && colonNum == 1
                && EntityFormat.isUrlAddress(str, dic) ) {
            wd = new Word(str, IWord.T_BASIC_LATIN, Entity.E_URL_A);
            wd.setPartSpeech(IWord.EN_POSPEECH);
            return wd;
        } else if ( pointNum == 2
                && (date = EntityFormat.isDate(str, '.')) != null ) {
            wd = new Word(date, IWord.T_BASIC_LATIN, Entity.E_DATETIME_YMD_A);
            wd.setPartSpeech(IWord.TIME_POSPEECH);
            return wd;
        } else if ( counter.get('-') >= 1
                && (date = EntityFormat.isDate(str, '-')) != null ) {
            String[] entity = counter.get('-') == 1
                    ? Entity.E_DATETIME_YM_A : Entity.E_DATETIME_YMD_A;
            wd = new Word(date, IWord.T_BASIC_LATIN, entity);
            wd.setPartSpeech(IWord.TIME_POSPEECH);
            return wd;
        } else if ( counter.get('/') >= 1
                && (date = EntityFormat.isDate(str, '/')) != null ) {
            String[] entity = counter.get('/') == 1
                    ? Entity.E_DATETIME_YM_A : Entity.E_DATETIME_YMD_A;
            wd = new Word(date, IWord.T_BASIC_LATIN, entity);
            wd.setPartSpeech(IWord.TIME_POSPEECH);
            return wd;
        } else if ( (tcount == 3 || tcount == 5)
                && colonNum >= 1 && EntityFormat.isTime(str) ) {
            String[] entity = colonNum == 1
                    ? Entity.E_DATETIME_HI_A : Entity.E_DATETIME_HIS_A;
            wd = new Word(str, IWord.T_BASIC_LATIN, entity);
            wd.setPartSpeech(IWord.TIME_POSPEECH);
            return wd;
        }

        /*
         * check the end condition.
         * and the check if the token loop was break by whitespace
         * cause there is no need to continue all the following work if it is.
        */
        if ( ch == -1 || _wspace ) {
            boolean isPercentage = false;
            for ( int i = isb.length() - 1; i > 0; i-- ) {
                if ( isb.charAt(i) == '%' ) {
                    if ( i > 0 && StringUtil.isEnNumeric(isb.charAt(i-1)) ) {
                        isPercentage = true;
                        break;
                    }
                } else if ( ! StringUtil.isEnPunctuation(isb.charAt(i)) ) {
                    break;
                }

                /*
                 * try to find a English and punctuation mixed word.
                 * this will clear all the punctuation until a mixed word is found.
                 * like "i love c++.", c++ will be found from token "c++.".
                */
                if ( dic.match(ILexicon.CJK_WORD, str) ) {
                    wd = dic.get(ILexicon.CJK_WORD, str).clone();
                    break;
                }

                pushBack(isb.charAt(i));
                isb.deleteCharAt(i);
                str = isb.toString();
            }

            if ( wd == null ) {
                if ( isPercentage ) {
                    wd = new Word(str, IWord.T_BASIC_LATIN,
                    		Entity.E_NUMERIC_PERCENTAGE_A);
                    wd.setPartSpeech(IWord.NUMERIC_POSPEECH);
                } else if ( tcount == 1 && StringUtil.isDigit(str) ) {
                    wd = new Word(str, IWord.T_BASIC_LATIN,
                    		Entity.E_NUMERIC_ARABIC_A);
                    wd.setPartSpeech(IWord.NUMERIC_POSPEECH);
                } else if ( tcount == 3 && StringUtil.isDecimal(str) ) {
                    wd = new Word(str, IWord.T_BASIC_LATIN,
                    		Entity.E_NUMERIC_DECIMAL_A);
                    wd.setPartSpeech(IWord.NUMERIC_POSPEECH);
                } else if ( dic.match(ILexicon.CJK_WORD, str) ) {
                    wd = dic.get(ILexicon.CJK_WORD, str).clone();
                } else {
                    wd = new Word(str, IWord.T_BASIC_LATIN);
                    wd.setPartSpeech(IWord.EN_POSPEECH);
                }
            }

            if ( wd.getPartSpeech() == null ) {
                wd.setPartSpeech(IWord.EN_POSPEECH);
            }

            return wd;
        }

        /*
         * the loop was broken by an unknown char and it is not a CJK char
         * 1, check if the end char is a special single unit char like '℉,℃' and so on ..
         * 2, or do it as the end stream way like (ch == -1 or _wspace == true)
        */
        if ( _check == false ) {
            /*
             * we check the units here, so we can recognize
             * many other units that is not Chinese like '℉,℃' and so on ...
            */
            boolean isDigit = StringUtil.isDigit(str);
            if ( isDigit || StringUtil.isDecimal(str) ) {
                ch = readNext();
                String unit = ((char)ch)+"";
                if ( dic.match(ILexicon.CJK_UNIT, unit) ) {
                    wd = getNumericUnitComposedWord(
                    		str, dic.get(ILexicon.CJK_UNIT, unit));
                } else {
                    String[] entity = isDigit
                    		? Entity.E_NUMERIC_ARABIC_A
                    				: Entity.E_NUMERIC_DECIMAL_A;
                    wd = new Word(str, IWord.T_BASIC_LATIN, entity);
                    wd.setPartSpeech(IWord.NUMERIC_POSPEECH);
                    pushBack(ch);
                }
            }

            if ( wd == null ) {
                if ( dic.match(ILexicon.CJK_WORD, str) ) {
                    wd = dic.get(ILexicon.CJK_WORD, str).clone();
                } else {
                    wd = new Word(str, IWord.T_BASIC_LATIN);
                }
            }

            if ( wd.getPartSpeech() == null ) {
                wd.setPartSpeech(IWord.EN_POSPEECH);
            }

            return wd;
        }

        /*
         * check and recognize the percentage
        */
        int length = isb.length();
        if ( length > 1 && isb.charAt(length-1) == '%'
                && StringUtil.isEnNumeric(isb.charAt(length-2)) ) {
            wd = new Word(str, IWord.T_BASIC_LATIN,
            		Entity.E_NUMERIC_PERCENTAGE_A);
            wd.setPartSpeech(IWord.NUMERIC_POSPEECH);
            return wd;
        }

        /*
         * check and get English and Chinese mixed word like 'B超, x射线'
         *
         * Attention:
         * make sure that (ch = readNext()) is after j < Config.MIX_CN_LENGTH.
         * or it cause the miss of the next char.
         *
         * @reader: (2013-09-25)
         * we do not check the type of the char read next.
         * so, words started with English and its length except the start English part
         * less than config.MIX_CN_LENGTH in the EC dictionary could be recognized.
         *
         * @Note added at 2017/08/05
         * Add the ibuffer.length checking logic to follow the limitation
         * of the maximum length of the current token
        */
        IStringBuffer ibuffer = new IStringBuffer(str);
        String tstr = null;
        int mc = 0, j = 0;        //the number of char that read from the stream.
        ialist.clear();
        for ( ; j < dic.mixSuffixLength
                && ibuffer.length() < config.MAX_LENGTH
                    && (ch = readNext()) != -1; j++ ) {
            /*
             * Attention:
             * it is a accident that Jcseg works fine for
             * we break the loop directly when we meet a whitespace.
             * 1, if a EC word is found, unit check process will be ignore.
             * 2, if matches no EC word, certainly return of readNext()
             *   will make sure the units check process works fine.
            */
            if ( StringUtil.isWhitespace(ch) ) {
                pushBack(ch);
                break;
            }

            ibuffer.append((char)ch);
            ialist.add(ch);
            tstr = ibuffer.toString();
            if ( dic.match(ILexicon.CJK_WORD, tstr) ) {
                wd  = dic.get(ILexicon.CJK_WORD, tstr);
                mc = j + 1;
            }
        }

        ibuffer.clear();
        ibuffer = null;                 //Let gc do it's work.
        for ( int i = j - 1; i >= mc; i-- ) {
            pushBack(ialist.get(i));    //push back the read chars.
        }

        if ( wd != null ) {
            wd = wd.clone();
            if ( wd.getPartSpeech() == null ) {
                wd.setPartSpeech(IWord.MIX_POSPEECH);
            }

            return wd;
        }

        /*
         * check the unit for the digit or the decimal Latin
        */
        boolean isDigit = StringUtil.isDigit(str);
        if ( isDigit || StringUtil.isDecimal(str) ) {
            ialist.clear();
            IWord unitWord = null;
            IStringBuffer sb = new IStringBuffer();
            for ( j = 0; j < config.MAX_UNIT_LENGTH
                    && (ch = readNext()) != -1; j++ ) {
                if ( StringUtil.isWhitespace(ch) ) {
                    pushBack(ch);
                    break;
                }

                sb.append((char)ch);
                ialist.add(ch);
                tstr = sb.toString();
                if ( dic.match(ILexicon.CJK_UNIT, tstr) ) {
                    unitWord = dic.get(ILexicon.CJK_UNIT, tstr);
                    mc = j + 1;
                }
            }

            if ( unitWord == null ) {
            	String[] entity = isDigit
                		? Entity.E_NUMERIC_ARABIC_A
                				: Entity.E_NUMERIC_DECIMAL_A;
                wd = new Word(str, IWord.T_BASIC_LATIN, entity);
                wd.setPartSpeech(IWord.NUMERIC_POSPEECH);
            } else {
            	wd = getNumericUnitComposedWord(str, unitWord);
            }

            for ( int i = j - 1; i >= mc; i-- ) {
                pushBack(ialist.get(i));
            }
        }

        /*
         * simply return the combination of English char, Arabic
         * numeric, English punctuation if matches no single units or EC word.
        */
        if ( wd == null ) {
            if ( dic.match(ILexicon.CJK_WORD, str) ) {
                wd = dic.get(ILexicon.CJK_WORD, str).clone();
            } else {
                wd = new Word(str, IWord.T_BASIC_LATIN);
            }

            if ( wd.getPartSpeech() == null ) {
                wd.setPartSpeech(IWord.EN_POSPEECH);
            }
        }

        return wd;
    }
417325
private void add(String pos, String s) {
		if(s.length()>maxLen)
			return;
		if(pos.length()==0)
			return;
		posSet.add(pos);
		if(dict.containsKey(s)){
			TreeSet<String> sett = dict.get(s);
			sett.add(pos);
		}else{
			TreeSet<String> sett  = new TreeSet<String>();
			sett.add(pos);
			dict.put(s, sett);
		}
	}
823138
@Override 
    protected IWord getNextCJKWord(int c, int pos) throws IOException
    {
        String key = null;
        char[] chars = nextCJKSentence(c);
        int cjkidx = 0, ignidx = 0, mnum = 0;
        IWord word = null;
        ArrayList<IWord> mList = new ArrayList<IWord>(8);
        
        while ( cjkidx < chars.length ) {
            /// @Note added at 2017/04/29
            /// check and append the single char word
            String sstr = String.valueOf(chars[cjkidx]);
            if ( dic.match(ILexicon.CJK_WORD, sstr) ) {
                IWord sWord = dic.get(ILexicon.CJK_WORD, sstr).clone();
                sWord.setPosition(pos+cjkidx);
                mList.add(sWord);
            }
            
            mnum = 0;
            isb.clear().append(chars[cjkidx]);
            //System.out.println("ignore idx: " + ignidx);
            for ( int j = 1; j < config.MAX_LENGTH 
                    && (cjkidx+j) < chars.length; j++ ) {
                isb.append(chars[cjkidx+j]);
                key = isb.toString();
                if ( dic.match(ILexicon.CJK_WORD, key) ) {
                    mnum   = 1;
                    ignidx = Math.max(ignidx, cjkidx + j);
                    word = dic.get(ILexicon.CJK_WORD, key).clone();
                    word.setPosition(pos+cjkidx);
                    mList.add(word);
                }
            }
            
            /*
             * no matches here:
             * should the current character chars[cjkidx] be a single word ?
             * lets do the current check 
            */
            if ( mnum == 0 && (cjkidx == 0 || cjkidx > ignidx) ) {
                String temp = String.valueOf(chars[cjkidx]);
                if ( ! dic.match(ILexicon.CJK_WORD, temp) ) {
                    word = new Word(temp, ILexicon.UNMATCH_CJK_WORD);
                    word.setPosition(pos+cjkidx);
                    mList.add(word);
                }
            }
            
            cjkidx++;
        }
        
        /*
         * do all the words analysis
         * 1, clear the stop words
         * 1, check and append the pinyin or synonyms words
        */
        for ( IWord w : mList ) {
            key = w.getValue();
            if ( config.CLEAR_STOPWORD 
                    && dic.match(ILexicon.STOP_WORD, key) ) {
                continue;
            }
            
            wordPool.add(w);
            appendWordFeatures(w);
        }
        
        //let gc do its work
        mList.clear();
        mList = null;
        
        return wordPool.size()==0 ? null : wordPool.remove();
    }
1254429
public void replaceChars(int startPosition, int endPosition, String replacement) {
    try {
      sourceBuilder.replace(startPosition, endPosition, replacement);
    } catch (StringIndexOutOfBoundsException e) {
      throw new IndexOutOfBoundsException(
          String.format(
              "Replacement cannot be made. Source file %s has length %d, requested start "
                  + "position %d, requested end position %d, replacement %s",
              path, sourceBuilder.length(), startPosition, endPosition, replacement));
    }
  }
346400
protected int replace_s(int c_bra, int c_ket, String s)
    {
	int adjustment = s.length() - (c_ket - c_bra);
	current.replace(c_bra, c_ket, s);
	limit += adjustment;
	if (cursor >= c_ket) cursor += adjustment;
	else if (cursor > c_bra) cursor = c_bra;
	return adjustment;
    }
775743
public final String getString(final int pos, String charsetName) {
        if (pos >= limit || pos < 0) throw new IllegalArgumentException("limit excceed: " + pos);

        byte[] buf = buffer;
        final int len = (0xff & buf[origin + pos]);
        if (pos + len + 1 > limit) throw new IllegalArgumentException("limit excceed: " + (pos + len + 1));

        try {
            return new String(buf, origin + pos + 1, len, charsetName);
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException("Unsupported encoding: " + charsetName, e);
        }
    }
645610
public final static int escape(final StringBuilder out, final char ch, final int pos)
    {
        switch (ch)
        {
        case '\\':
        case '[':
        case ']':
        case '(':
        case ')':
        case '{':
        case '}':
        case '#':
        case '"':
        case '\'':
        case '.':
        case '>':
        case '<':
        case '*':
        case '+':
        case '-':
        case '_':
        case '!':
        case '`':
        case '^':
            out.append(ch);
            return pos + 1;
        default:
            out.append('\\');
            return pos;
        }
    }
223126
public static void replace(final StringBuffer sb, final String find, final String replacement) {
		int pos = 0;
		while(pos<sb.length()) {
			pos = sb.indexOf(find, pos);
			if(pos==-1) break;
			sb.replace(pos, pos+find.length(), replacement);
			pos += replacement.length();
		}
	}