How to split string based on length and space using Java - java

I'm having a string as following in Java. The length of the string is not known and as an example it will be something like below.
String str = "I love programming. I'm currently working with Java and C++."
For some requirement I want to get first 15 characters. Then 30, 45, 70 next characters. Once the string was split if the name was not meaningful then it should be split from nearest space. For the above example output is as following.
String strSpli1 = "I love "; //Since 'programming' is splitting it was sent to next split
String strSpli2 = "programming. I'm currently ";//Since 'working' is splitting it was sent to next split
String strSpli3 = "working with Java and C++.";
Please help me to achieve this.
Updated answer for anybody having this kind of requirement.
String str = "I love programming. I'm currently working with Java and C++.";
String strSpli1 = "";
String strSpli2 = "";
String strSpli3 = "";
try {
strSpli1 = str.substring(15);
int pos = str.lastIndexOf(" ", 16);
if (pos == -1) {
pos = 15;
}
strSpli1 = str.substring(0, pos);
str = str.substring(pos);
try {
strSpli2 = str.substring(45);
int pos1 = str.lastIndexOf(" ", 46);
if (pos1 == -1) {
pos1 = 45;
}
strSpli2 = str.substring(0, pos1);
str = str.substring(pos1);
try {
strSpli3 = str.substring(70);
int pos2 = str.lastIndexOf(" ", 71);
if (pos2 == -1) {
pos2 = 45;
}
strSpli3 = str.substring(0, pos2);
str = str.substring(pos2);
} catch (Exception ex) {
strSpli3 = str;
}
} catch (Exception ex) {
strSpli2 = str;
}
} catch (Exception ex) {
strSpli1 = str;
}
Thank you

use the 2 parameter version of lastIndexOf() to search for space backwards starting from a given position. Example for the first 15 characters:
int pos = str.lastIndexOf(" ", 16);
if (pos == -1) {
pos = 15;
}
String found = str.substring(0, pos);
str = str.substring(pos+1);
this is missing checks like ensuring the string starts with at least 15 characters, or that pos+1 is valid for given length
suggest having a look at java.text.BreakIterator

why you use so many try catch ? just try this.
public class MyClass {
public static void main(String args[]) {
String str = "I love programming. I'm currently working with Java and C++.";
String strSpli1 = "";
String strSpli2 = "";
String strSpli3 = "";
strSpli1 = str.substring(0, 7);
strSpli2 = str.substring(7, 33);
strSpli3 = str.substring(34, str.length());
System.out.println(strSpli1+"\n");
System.out.println(strSpli2+"\n");
System.out.println(strSpli3+"\n");
}
use substring(start index, end index).

Related

Identify whether my string contains any hex code or not in java

I want to identify whether my string contains any hex code or not.
Use cases
String input1 = "hello check this input ";
String input2 = "hello check 0x740x680x690x73 input";
String input3 = "0x680x650x6c0x6c0x6f0x200x630x680x650x630x6b0x200x740x680x690x730x200x690x6e0x700x750x74";
isContainHex(input1) should return false
isContainHex(input2) should return true
isContainHex(input3) should return true
I have tried
String input2 = "hello check 0x740x680x690x73 input";
if(input2.contains("0x") || input2.contains("\\x"))
{
System.out.println("string contains hex");
}
and I am able to find hex but,
If My input contains hex like
String input4 = "h68h65h6ch6ch6f check this input ";
Here I cant check input4.contains("h")
Any one have solution for this?
is there any standard library by which I can achive same?
Update
I have wrote following code, and its working well but taking time.
Now can it be optimize
try
{
if (input != null && input.trim().length() > 0)
{
String originalHex = null;
StringBuilder output = new StringBuilder();
String inputArray[] = null;
if (StringUtils.countMatches(input, "\\x") > 3)
{
originalHex = input.substring(input.indexOf("\\x"), input.lastIndexOf("\\x", input.length()) + 4);
inputArray = input.split("\\Q\\x\\E");
}
else if (StringUtils.countMatches(input, "0x") > 3)
{
originalHex = input.substring(input.indexOf("0x"), input.lastIndexOf("0x", input.length()) + 4);
inputArray = input.split("0x");
}
if (inputArray != null && inputArray.length > 0)
{
for (String str: inputArray)
{
int strLength = str.trim().length();
if (strLength == 2)
{
output.append((char)Integer.parseInt(str, 16));
}
else if (strLength > 2)
{
if (strLength % 2 != 0)
{
strLength = strLength - 1;
}
for (int i = 0; i < strLength; i += 2)
{
String val = str.substring(i, i+2);
if (val.matches("\\d+"))
{
output.append((char)Integer.parseInt(val, 16));
}
}
}
}
input = input.replaceAll("\\Q" + originalHex + "\\E", output.toString());
}
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
syso(input);

How to add characters to a string in specific indexes?

I have a string formed with 6 letters eg: "abcdef".
I need to add "." every two characters so it would be like this: "ab.cd.ef".
I'm working in java, I tried this:
private String FormatAddress(String sourceAddress) {
char[] sourceAddressFormatted = new char[8];
sourceAddress.getChars(0, 1, sourceAddressFormatted, 0);
sourceAddress += ".";
sourceAddress.getChars(2, 3, sourceAddressFormatted, 3);
sourceAddress += ".";
sourceAddress.getChars(4, 5, sourceAddressFormatted, 6);
String s = new String(sourceAddressFormatted);
return s;
}
But i received strange values such as [C#2723b6.
Thanks in advance:)
Try regexp:
Input:
abcdef
Code:
System.out.println("abcdef".replaceAll(".{2}(?!$)", "$0."));
Output:
ab.cd.ef
You should fix it as
String sourceAddress = "abcdef";
String s = sourceAddress.substring(0, 2);
s += ".";
s += sourceAddress.substring(2, 4);
s += ".";
s += sourceAddress.substring(4, 6);
System.out.println(s);
You also can do the same with regex, it's a one line solution
String s = sourceAddress.replaceAll("(\\w\\w)(?=\\w\\w)", "$1.");
System.out.println(s);
private String formatAddress(String sourceAddress) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < sourceAddress.length(); i+=2) {
sb.append(sourceAddress.substring(i, i+2));
if (i != sourceAddress.length()-1) {
sb.append('.');
}
}
return sb.toString();
}
Try this:
String result="";
String str ="abcdef";
for(int i =2; i<str.length(); i=i+2){
result = result + str.substring(i-2 , i) + ".";
}
result = result + str.substring(str.length()-2);

Java's String .replaceFirst is not working and I don't know if its a bug or I did it wrong

Ok I have a method that is replacing text when I use string.replace() it works but when I switch to relpaceFirst() as shown below it no longer works, what am I doing wrong or missing here?
private void acceptAccButtonActionPerformed(java.awt.event.ActionEvent evt) {
int selectedAcTableItem = validAcTable.getSelectedRow();
int selectedSugTableItem = suggestedAcTable.getSelectedRow();
if (selectedAcTableItem > 0) {
String acNameDefthmlText = htmlText;
String parensName = "";
String acName = validAcTable.getValueAt(selectedAcTableItem, 0).toString();
String acDef = validAcTable.getValueAt(selectedAcTableItem, 1).toString();
String acSent = validAcTable.getValueAt(selectedAcTableItem, 2).toString();
StringBuilder acBuilder = new StringBuilder(acDef);
acBuilder.append(" (").append(acName).append(")");
if (!acDef.equals("")) {
parensName = " (" + acName + ")";
if (htmlText.contains(acName) && !htmlText.contains(acBuilder)){
String acReplace = acBuilder.toString();
String acOrigDefName = acDefRow + parensName;
if (htmlText.contains(acOrigDefName) && parensName.contains(acOrigName)){
acNameDefthmlText = htmlText.replaceFirst(acOrigDefName, acReplace);
} else if (htmlText.contains(acName)) {
acNameDefthmlText = htmlText.replaceFirst(acName, acReplace);
}
htmlText = acNameDefthmlText;
}
validAcTable.setValueAt(true, selectedAcTableItem, 2);
Acronym acronym = createNewAcronym(acName, acSent, acDef, true);
try {
AcronymDefinitionController.sharedInstance().writeAcronymToExcelSheet(acName, acDef);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
} catch (InvalidFormatException ex) {
Exceptions.printStackTrace(ex);
}
if (validAcTable.getRowCount() - 1 >= validAcTable.getSelectedRow() + 1) {
validAcTable.changeSelection(selectedAcTableItem + 1, 0, true, true);
}
validAcTable.repaint();
}
}
If you notice the signature of two methods in question:
replace(char oldChar,char newChar);
replace(CharSequence target, CharSequence replacement);
replaceFirst(String regex, String replacement);
As you can see, in replaceFirst you matching argument is treated as regex(regular expression), which will cause the difference if any special chars are involved in the argument.
For example: consider below:
System.out.println("abcdab".replace("ab", "ef")); //<- replaces all
System.out.println("abcdab".replaceFirst("ab", "ef"));//<-replaces first
System.out.println("\\abcdab".replace("\\ab", "ef")); //<-replaces first
System.out.println("\\abcdab".replaceFirst("\\ab", "ef"));
//^ doesn't replace as `\` is an special char

Words inside square brackes - RegExp

String linkPattern = "\\[[A-Za-z_0-9]+\\]";
String text = "[build]/directory/[something]/[build]/";
RegExp reg = RegExp.compile(linkPattern,"g");
MatchResult matchResult = reg.exec(text);
for (int i = 0; i < matchResult.getGroupCount(); i++) {
System.out.println("group" + i + "=" + matchResult.getGroup(i));
}
I am trying to get all blocks which are encapsulated by squared bracets form a path string:
and I only get group0="[build]" what i want is:
1:"[build]" 2:"[something]" 3:"[build]"
EDIT:
just to be clear words inside the brackets are generated with random text
public static String genText()
{
final int LENGTH = (int)(Math.random()*12)+4;
StringBuffer sb = new StringBuffer();
for (int x = 0; x < LENGTH; x++)
{
sb.append((char)((int)(Math.random() * 26) + 97));
}
String str = sb.toString();
str = str.substring(0,1).toUpperCase() + str.substring(1);
return str;
}
EDIT 2:
JDK works fine, GWT RegExp gives this problem
SOLVED:
Answer from Didier L
String linkPattern = "\\[[A-Za-z_0-9]+\\]";
String result = "";
String text = "[build]/directory/[something]/[build]/";
RegExp reg = RegExp.compile(linkPattern,"g");
MatchResult matchResult = null;
while((matchResult=reg.exec(text)) != null){
if(matchResult.getGroupCount()==1)
System.out.println( matchResult.getGroup(0));
}
I don't know which regex library you are using but using the one from the JDK it would go along the lines of
String linkPattern = "\\[[A-Za-z_0-9]+\\]";
String text = "[build]/directory/[something]/[build]/";
Pattern pat = Pattern.compile(linkPattern);
Matcher mat = pat.matcher(text);
while (mat.find()) {
System.out.println(mat.group());
}
Output:
[build]
[something]
[build]
Try:
String linkPattern = "(\\[[A-Za-z_0-9]+\\])*";
EDIT:
Second try:
String linkPattern = "\\[(\\w+)\\]+"
Third try, see http://rubular.com/r/eyAQ3Vg68N

Java File I/O help

I have a problem with my code. I need to do several operations on a log file with this structure:
190.12.1.100 2011-03-02 12:12 test.html
190.12.1.100 2011-03-03 13:18 data.html
128.33.100.1 2011-03-03 15:25 test.html
128.33.100.1 2011-03-04 18:30 info.html
I need to get the number of visits per month, number of visits per page and number of unique visitors based on the IP. That is not the question, I managed to get all three operations working. The problem is, only the first choice runs correctly while the other choices just return values of 0 afterwards, as if the file is empty, so i am guessing i made a mistake with the I/O somewhere. Here's the code:
import java.io.*;
import java.util.*;
public class WebServerAnalyzer {
private Map<String, Integer> hm1;
private Map<String, Integer> hm2;
private int[] months;
private Scanner input;
public WebServerAnalyzer() throws IOException {
hm1 = new HashMap<String, Integer>();
hm2 = new HashMap<String, Integer>();
months = new int[12];
for (int i = 0; i < 12; i++) {
months[i] = 0;
}
File file = new File("webserver.log");
try {
input = new Scanner(file);
} catch (FileNotFoundException fne) {
input = null;
}
}
public String nextLine() {
String line = null;
if (input != null && input.hasNextLine()) {
line = input.nextLine();
}
return line;
}
public int getMonth(String line) {
StringTokenizer tok = new StringTokenizer(line);
if (tok.countTokens() == 4) {
String ip = tok.nextToken();
String date = tok.nextToken();
String hour = tok.nextToken();
String page = tok.nextToken();
StringTokenizer dtok = new StringTokenizer(date, "-");
if (dtok.countTokens() == 3) {
String year = dtok.nextToken();
String month = dtok.nextToken();
String day = dtok.nextToken();
int m = Integer.parseInt(month);
return m;
}
}
return -1;
}
public String getIP(String line) {
StringTokenizer tok = new StringTokenizer(line);
if (tok.countTokens() == 4) {
String ip = tok.nextToken();
String date = tok.nextToken();
String hour = tok.nextToken();
String page = tok.nextToken();
StringTokenizer dtok = new StringTokenizer(date, "-");
return ip;
}
return null;
}
public String getPage(String line) {
StringTokenizer tok = new StringTokenizer(line);
if (tok.countTokens() == 4) {
String ip = tok.nextToken();
String date = tok.nextToken();
String hour = tok.nextToken();
String page = tok.nextToken();
StringTokenizer dtok = new StringTokenizer(date, "-");
return page;
}
return null;
}
public void visitsPerMonth() {
String line = null;
do {
line = nextLine();
if (line != null) {
int m = getMonth(line);
if (m != -1) {
months[m - 1]++;
}
}
} while (line != null);
// Print the result
String[] monthName = {"JAN ", "FEB ", "MAR ",
"APR ", "MAY ", "JUN ", "JUL ", "AUG ", "SEP ",
"OCT ", "NOV ", "DEC "};
for (int i = 0; i < 12; i++) {
System.out.println(monthName[i] + months[i]);
}
}
public int count() throws IOException {
InputStream is = new BufferedInputStream(new FileInputStream("webserver.log"));
try {
byte[] c = new byte[1024];
int count = 0;
int readChars = 0;
while ((readChars = is.read(c)) != -1) {
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\n')
++count;
}
}
return count;
} finally {
is.close();
}
}
public void UniqueIP() throws IOException{
String line = null;
for (int x = 0; x <count(); x++){
line = nextLine();
if (line != null) {
if(hm1.containsKey(getIP(line)) == false) {
hm1.put(getIP(line), 1);
} else {
hm1.put(getIP(line), hm1.get(getIP(line)) +1 );
}
}
}
Set set = hm1.entrySet();
Iterator i = set.iterator();
System.out.println("\nNumber of unique visitors: " + hm1.size());
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
System.out.print(me.getKey() + " - ");
System.out.println(me.getValue() + " visits");
}
}
public void pageVisits() throws IOException{
String line = null;
for (int x = 0; x <count(); x++){
line = nextLine();
if (line != null) {
if(hm2.containsKey(getPage(line)) == false)
hm2.put(getPage(line), 1);
else
hm2.put(getPage(line), hm2.get(getPage(line)) +1 );
}
}
Set set = hm2.entrySet();
Iterator i = set.iterator();
System.out.println("\nNumber of pages visited: " + hm2.size());
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
System.out.print(me.getKey() + " - ");
System.out.println(me.getValue() + " visits");
}
}
Any help figuring out the problem would be much appreciated as I am quite stuck.
I didn't read the code thoroughly yet, but I guess you're not setting the read position back to the beginning of the file when you start a new operation. Thus nextLine() would return null.
You should create a new Scanner for each operation and close it afterwards. AFAIK scanner doesn't provide a method to go back to the first byte.
Currently I could also think of 3 alternatives:
Use a BufferedReader and call reset() for each new operation. This should cause the reader to go back to byte 0 provided you didn't call mark() somewhere.
Read the file contents once and iterate over the lines in memory, i.e. put all lines into a List<String> and then start at each line.
Read the file once, parse each line and construct an apropriate data structure that contains the data you need. For example, you could use a TreeMap<Date, Map<Page, Map<IPAdress, List<Visit>>>>, i.e. you'd store the visits per ip address per page for each date. You could then select the appropriate submaps by date, page and ip address.
The reset method of BufferedReader that Thomas recommended would only work if the file size is smaller than the buffer size or if you called mark with a large enough read ahead limit.
I would recommend reading throught the file once and to update your maps and month array for each line. BTW, you don't need a Scanner just to read lines, BufferedReader has a readLine method itself.
BufferedReader br = ...;
String line;
while (null != (line = br.readLine())) {
String ip = getIP(line);
String page = getPage(line);
int month = getMonth(line);
// update hashmaps and arrays
}

Categories

Resources