Reputation: 480
I am new to regular expressions.
Is it possible to match everything before a word that meets a certain criteria:
E.g.
THIS IS A TEST - - +++ This is a test
I would like it to encounter a word that begins with an uppercase and the next character is lower case. This constitutes a proper word. I would then like to delete everything before that word.
The example above should produce: This is a test
I only want to this processing until it finds the proper word and then stop.
Any help would be appreciated.
Thanks
Upvotes: 20
Views: 55932
Reputation: 62759
I really don't get why people go to regular expressions so quickly.
I've done a lot of string parsing (Used to screen-scrape vt100 menu screens) and I've never found a single case where Regular Expressions would have been much easier than just writing code. (Maybe a couple would have been a little easier, but not much).
I kind of understand they are supposed to be easier once you know them--but you see someone ask a question like this and realize they aren't easy for every programmer to just get by glancing at it. If it costs 1 programmer somewhere down the line 10 minutes of thought, it has a huge net loss over just coding it, even if you took 5 minutes to write 5 lines.
So it's going to need documentation--and if someone who is at that same level comes across it, he won't be able to modify it without knowledge outside his domain, even with documentation.
I mean if the poster had to ask on a trivial case--then there just isn't such thing as a trivial case.
public String getRealText(String scanMe) {
for(int i=0 ; i < scanMe.length ; i++)
if( isUpper(scanMe[i]) && isLower(scanMe[i+1]) )
return scanMe.subString(i);
return null; }
I mean it's 5 lines, but it's simple, readable, and faster than most (all?) RE parsers. Once you've wrapped a regular expression in a method and commented it, the difference in size isn't measurable. The difference in time--well for the poster it would have obviously been a LOT less time--as it might be for the next guy that comes across his code.
And this string operation is one of the ones that are even easier in C with pointers--and it would be even quicker since the testing functions are macros in C.
By the way, make sure you look for a space in the second slot, not just a lower case variable, otherwise you'll miss any lines starting with the words A or I.
Upvotes: 1
Reputation: 1499860
Having woken up a bit, you don't need to delete anything, or even create a sub-group - just find the pattern expressed elsewhere in answers. Here's a complete example:
import java.util.regex.*;
public class Test
{
public static void main(String args[])
{
Pattern pattern = Pattern.compile("[A-Z][a-z].*");
String original = "THIS IS A TEST - - +++ This is a test";
Matcher match = pattern.matcher(original);
if (match.find())
{
System.out.println(match.group());
}
else
{
System.out.println("No match");
}
}
}
EDIT: Original answer
This looks like it's doing the right thing:
import java.util.regex.*;
public class Test
{
public static void main(String args[])
{
Pattern pattern = Pattern.compile("^.*?([A-Z][a-z].*)$");
String original = "THIS IS A TEST - - +++ This is a test";
String replaced = pattern.matcher(original).replaceAll("$1");
System.out.println(replaced);
}
}
Basically the trick is not to ignore everything before the proper word - it's to group everything from the proper word onwards, and replace the whole text with that group.
The above would fail with "*** FOO *** I am fond of peanuts"
because the "I" wouldn't be considered a proper word. If you want to fix that, change the [a-z] to [a-z\s] which will allow for whitespace instead of a letter.
Upvotes: 3
Reputation: 39750
then you can do something like this
'.*([A-Z][a-z].*)\s*'
.* matches anything
( [A-Z] #followed by an uper case char
[a-z] #followed by a lower case
.*) #followed by anything
\s* #followed by zeror or more white space
Which is what you are looking for I think
Upvotes: 0
Reputation: 338148
Replace
^.*?(?=[A-Z][a-z])
with the empty string. This works for ASCII input. For non-ASCII input (Unicode, other languages), different strategies apply.
Explanation
.*? Everything, until
(?= followed by
[A-Z] one of A .. Z and
[a-z] one of a .. z
)
The Java Unicode-enabled variant would be this:
^.*?(?=\p{Lu}\p{Ll})
Upvotes: 49