Regular Expression - big problem with replacement

H

Henner Graubitz

Hi all,

is there a nice solution to show what string has been replaced by
java.util.regex?

For example: following code:


String replacement = "$1.01.$3";

Pattern p = Pattern.compile("([0-9]{1,2})\\.[\\ ]*(Januar|Jan[\\.]?)[\\
]*([\\d]{2,4})");

Matcher m = p.matcher("one cat on 18. Januar 1974 and two cats on 1.
Januar 1871 has been hidden in the yard");
String newString = m.replaceAll(replacement);

while (m.find()) {
System.out.println("Start -> " + m.start()); // returns start
position of the OLD String
System.out.println("End -> " + m.end()); // returns end
position of the OLD String
System.out.println("Group -> " + m.group()); // returns the match
in the OLD String
counter ++;
}

System.out.println("newString -> " + newString); // returns the new
string


---> The output looks like


Start -> 11
End -> 26
Group -> 18. Januar 1974
Start -> 40
End -> 54
Group -> 1. Januar 1871
newString -> one cat am 18.01.1974 two sowie am 1.01.1871 cats in the yard

That is ok, but WHAT I WANT IS THE REPLACEMENT

a) 18.01.1974 and b) 1.01.1871

Is there any nice solutuion ?


Thanks for any advice

Henner Graubitz
 
V

Virgil Green

Henner Graubitz said:
Hi all,

is there a nice solution to show what string has been replaced by
java.util.regex?

For example: following code:


String replacement = "$1.01.$3";

Pattern p = Pattern.compile("([0-9]{1,2})\\.[\\ ]*(Januar|Jan[\\.]?)[\\
]*([\\d]{2,4})");

Matcher m = p.matcher("one cat on 18. Januar 1974 and two cats on 1.
Januar 1871 has been hidden in the yard");
String newString = m.replaceAll(replacement);

while (m.find()) {
System.out.println("Start -> " + m.start()); // returns start
position of the OLD String
System.out.println("End -> " + m.end()); // returns end
position of the OLD String
System.out.println("Group -> " + m.group()); // returns the match
in the OLD String
counter ++;
}

System.out.println("newString -> " + newString); // returns the new
string


---> The output looks like


Start -> 11
End -> 26
Group -> 18. Januar 1974
Start -> 40
End -> 54
Group -> 1. Januar 1871
newString -> one cat am 18.01.1974 two sowie am 1.01.1871 cats in the yard

The text here has changed as well ('on' to 'am', etc). Cut-and-paste error?
That is ok, but WHAT I WANT IS THE REPLACEMENT

a) 18.01.1974 and b) 1.01.1871

Perhaps I'm being obtuse, but I fail to see the difference between what you
reported and what you said you wanted.

- Virgil
 
H

Henner Graubitz

Hi Virgil,

first of all: yes, an cut and paste error because I changed the example from
national to international.


Well, to make the example more clear: look at the String replacement.

"$1.01.$3"

This String is responisble for replacing 18. Januar 1974 to 18.01.1974 AND
1. Januar 1871 to 1.01.1871.

What I want to receive is the new String 18.01.1974 and 1.01.1871.

If I do a System.out.println(replacement) I receive: $1.01.$3.

But I want a function or method which let me receive:

1.: 18.01.1974
2.: 1.01.1871


At the moment I am working with split to receive the string around
the match, use the output to compute the char - positions in the changed
string
and to receive the
replacements. But the question is: is their a better solution.

Thanks for advise

Henner Graubitz




Virgil said:
Hi all,

is there a nice solution to show what string has been replaced by
java.util.regex?

For example: following code:


String replacement = "$1.01.$3";

Pattern p = Pattern.compile("([0-9]{1,2})\\.[\\ ]*(Januar|Jan[\\.]?)[\\
]*([\\d]{2,4})");

Matcher m = p.matcher("one cat on 18. Januar 1974 and two cats on 1.
Januar 1871 has been hidden in the yard");
String newString = m.replaceAll(replacement);

while (m.find()) {
System.out.println("Start -> " + m.start()); // returns start
position of the OLD String
System.out.println("End -> " + m.end()); // returns end
position of the OLD String
System.out.println("Group -> " + m.group()); // returns the match
in the OLD String
counter ++;
}

System.out.println("newString -> " + newString); // returns the new
string


---> The output looks like


Start -> 11
End -> 26
Group -> 18. Januar 1974
Start -> 40
End -> 54
Group -> 1. Januar 1871
newString -> one cat am 18.01.1974 two sowie am 1.01.1871 cats in the yard


The text here has changed as well ('on' to 'am', etc). Cut-and-paste error?

That is ok, but WHAT I WANT IS THE REPLACEMENT

a) 18.01.1974 and b) 1.01.1871


Perhaps I'm being obtuse, but I fail to see the difference between what you
reported and what you said you wanted.

- Virgil
 
V

Virgil Green

Henner Graubitz said:
Hi Virgil,

first of all: yes, an cut and paste error because I changed the example from
national to international.


Well, to make the example more clear: look at the String replacement.

"$1.01.$3"

This String is responisble for replacing 18. Januar 1974 to 18.01.1974 AND
1. Januar 1871 to 1.01.1871.

What I want to receive is the new String 18.01.1974 and 1.01.1871.

If I do a System.out.println(replacement) I receive: $1.01.$3.

But I want a function or method which let me receive:

1.: 18.01.1974
2.: 1.01.1871


At the moment I am working with split to receive the string around
the match, use the output to compute the char - positions in the changed
string
and to receive the
replacements. But the question is: is their a better solution.

Are you saying that you *don't* want the original string with the converted
dates, but rather you want to printout the two converted dates by
themselves? I'm still having a hard time understanding what you're trying to
achieve.

- Virgil
 
H

Henner Graubitz

Hi Virgil,

yes, you are right. I do not want the old string, I want to get the two
NEW REPLACEMENTS (as I wrote twice)

First output: 18.01.1974
Second output: 1.01.1871

Thats it. So if you have a suggestion how to get them I will say many
thanks.

Enjoy

Henner Graubitz
 
V

Virgil Green

Henner Graubitz said:
Hi Virgil,

yes, you are right. I do not want the old string, I want to get the two
NEW REPLACEMENTS (as I wrote twice)

First output: 18.01.1974
Second output: 1.01.1871

Thats it. So if you have a suggestion how to get them I will say many
thanks.

Enjoy

Henner Graubitz

Since you've shown no code attempting what you want (the code show has only
demonstrated what you *don't* want) it was very difficult to discern that
your desired output examples were discrete outputs rather than just
designations of the two replacements into the original string.

Regardless, perhaps what you want is the groupCount() method followed by a
for or while loop that uses group(int) and replaceAll on the output of the
group(int) method. All are methods on Matcher.

- Virgil
 
A

Alan Moore

Hi Virgil,

first of all: yes, an cut and paste error because I changed the example from
national to international.


Well, to make the example more clear: look at the String replacement.

"$1.01.$3"

This String is responisble for replacing 18. Januar 1974 to 18.01.1974 AND
1. Januar 1871 to 1.01.1871.

What I want to receive is the new String 18.01.1974 and 1.01.1871.

If I do a System.out.println(replacement) I receive: $1.01.$3.

But I want a function or method which let me receive:

1.: 18.01.1974
2.: 1.01.1871


At the moment I am working with split to receive the string around
the match, use the output to compute the char - positions in the changed
string
and to receive the
replacements. But the question is: is their a better solution.

Thanks for advise

Henner Graubitz

You can use the appendReplacement() and appendTail() methods of the
Matcher class to write your own replaceAll() method. That allows you
to extract the replacement text at the same time as you do the
replacement, instead of doing it in a separate pass. Here's an
example:

import java.util.regex.*;

public class Tester
{
public static void main(String[] args)
{
String input = "one cat on 18. Januar 1974 and two " +
"cats on 1. Januar 1871 has been hidden in the yard";
String regex = "(\\d{1,2})\\. *(Januar|Jan\\.?) *(\\d{2,4})";
System.out.println(input);

Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
StringBuffer sb = new StringBuffer();

int diff = 0;
while (m.find())
{
m.appendReplacement(sb, "$1.01.$3");
System.out.println(sb.substring(m.start() + diff));
diff += sb.length() - m.end();
}
m.appendTail(sb);

System.out.println(sb.toString());
}
}
 
H

Henner Graubitz

Thank you Alan,

you solved my problem. :)))

Henner





Alan said:
Hi Virgil,

first of all: yes, an cut and paste error because I changed the example from
national to international.


Well, to make the example more clear: look at the String replacement.

"$1.01.$3"

This String is responisble for replacing 18. Januar 1974 to 18.01.1974 AND
1. Januar 1871 to 1.01.1871.

What I want to receive is the new String 18.01.1974 and 1.01.1871.

If I do a System.out.println(replacement) I receive: $1.01.$3.

But I want a function or method which let me receive:

1.: 18.01.1974
2.: 1.01.1871


At the moment I am working with split to receive the string around
the match, use the output to compute the char - positions in the changed
string
and to receive the
replacements. But the question is: is their a better solution.

Thanks for advise

Henner Graubitz


You can use the appendReplacement() and appendTail() methods of the
Matcher class to write your own replaceAll() method. That allows you
to extract the replacement text at the same time as you do the
replacement, instead of doing it in a separate pass. Here's an
example:

import java.util.regex.*;

public class Tester
{
public static void main(String[] args)
{
String input = "one cat on 18. Januar 1974 and two " +
"cats on 1. Januar 1871 has been hidden in the yard";
String regex = "(\\d{1,2})\\. *(Januar|Jan\\.?) *(\\d{2,4})";
System.out.println(input);

Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
StringBuffer sb = new StringBuffer();

int diff = 0;
while (m.find())
{
m.appendReplacement(sb, "$1.01.$3");
System.out.println(sb.substring(m.start() + diff));
diff += sb.length() - m.end();
}
m.appendTail(sb);

System.out.println(sb.toString());
}
}
 
V

Virgil Green

(top posting corrected for my reading pleasure)
Clever in this case ... and not a Java and Newsgroup newbie like you.

Now that is quite humorous. Why have you turned to name calling when I've
only asked you to post complete code, explained why I did not understand
your previous question, and do not know whether you even attempted to use
the information I provided regarding your question... once I finally had a
clear picture of what you were asking?

- Virgil
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top