Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regular expression to split by forward slash

Tags:

java

regex

I have a parse tree which includes some information. To extract the information that I need, I am using a code which splits the string based on forward slash (/), but that is not a perfect code. I explain more details here:

I had used this code in another project earlier and that worked perfectly. But now the parse trees of my new dataset are more complicated and the code makes wrong decisions sometimes.

The parse tree is something like this:

(TOP~did~1~1 (S~did~2~2 (NPB~I~1~1 I/PRP ) (VP~did~3~1 did/VBD not/RB (VP~read~2~1 read/VB (NPB~article~2~2 the/DT article/NN ./PUNC. ) ) ) ) ) 

As you see, the leaves of the tree are the words right before the forward slashes. To get these words, I have used this code before:

parse_tree.split("/");

But now, in my new data, I see instances like these:

1) (TOP Source/NN http://www.alwatan.com.sa/daily/2007-01-31/first_page/first_page01.htm/X ./. )

where there are multiple slashes due to website addresses (In this case, only the last slash is the separator of the word).

2) (NPB~sister~2~2 Your/PRP$ sister/NN //PUNC: )

Where the slash is a word itself.

Could you please help me to replace my current simple regular expression with an expression which can manage these cases?

To summarize what I need, I would say that I need a regular expression which can split based on forward slash, but it must be able to manage two exceptions: 1) if there is a website address, it must split based on the last slash. 2) If there are two consecutive slashes, it must split based on the second split (and the first slash must NOT be considered as a separator, it is a WORD).

like image 733
user1419243 Avatar asked May 08 '15 10:05

user1419243


People also ask

What does forward slash do in regex?

The forward slash character is used to denote the boundaries of the regular expression: ? The backslash character ( \ ) is the escaping character. It can be used to denote an escaped character, a string, literal, or one of the set of supported special characters.

Can we use regex in Split?

You do not only have to use literal strings for splitting strings into an array with the split method. You can use regex as breakpoints that match more characters for splitting a string.

Do I need to escape forward slash in regex?

A slash symbol '/' is not a special character, but in JavaScript, it is used to open and close the RegEx: /... pattern.../ , so we should escape it too.

What is double slash in regex?

means, "match the 'period' as a literal character". If you don't have the backslash "escape character", the in most Regexp engines means, "match any character". Follow this answer to receive notifications.


2 Answers

I achieved what you requested following this article:

http://www.rexegg.com/regex-best-trick.html

Just to summarize, here is the over all strategy:

1st, you will need to create a Regex in this format:

NotThis | NeitherThis | (IWantThis)

After that, your capture group $1 will contain only the slashes you are interested in perform the splits.

You can then replace them with something less likely to occur, and after that you perform the split in this replaced term.

So, having this strategy in mind, here's the code:

Regex:

\\/(?=\\/)|(?:http:\\/\\/)?www[\\w\\.\\/\\-]*(?=\\/)|(\\/)

Explanation:

NotThis term would be double slashes with lookAhead( to take just 1st slash)

\\/(?=\\/)

NeitherThis term is just a basic url check with a lookahead to not capture the last \/

(?:http:\\/\\/)?www[\\w\\.\\/\\-]*(?=\\/)

IWantThis term is simply the slash:

(\\/)

In the Java code you can put this all together doing something like this:

Pattern p = Pattern.compile("\\/(?=\\/)|(?:http:\\/\\/)?www[\\w\\.\\/\\-]*(?=\\/)|(\\/)");

Matcher m = p.matcher("(TOP~did~1~1 (S~did~2~2 (NPB~I~1~1 I/PRP ) (VP~did~3~1 did/VBD not/RB (VP~read~2~1 read/VB (NPB~article~2~2 the/DT article/NN ./PUNC. ) ) ) ) )\n(TOP Source/NN http://www.alwatan.com.sa/daily/2007-01-31/first_page/first_page01.htm/X ./. )\n(NPB~sister~2~2 Your/PRP$ sister/NN //PUNC: )");
StringBuffer b= new StringBuffer();
while (m.find()) {
    if(m.group(1) != null) m.appendReplacement(b, "Superman");
    else m.appendReplacement(b, m.group(0));
}
m.appendTail(b);
String replaced = b.toString();
System.out.println("\n" + "*** Replacements ***");
System.out.println(replaced);

String[] splits = replaced.split("Superman");
System.out.println("\n" + "*** Splits ***");
for (String split : splits) System.out.println(split);

Output:

*** Replacements ***                                                                                                                                                                                  
(TOP~did~1~1 (S~did~2~2 (NPB~I~1~1 ISupermanPRP ) (VP~did~3~1 didSupermanVBD notSupermanRB (VP~read~2~1 readSupermanVB (NPB~article~2~2 theSupermanDT articleSupermanNN .SupermanPUNC. ) ) ) ) )      
(TOP SourceSupermanNN http://www.alwatan.com.sa/daily/2007-01-31/first_page/first_page01.htmSupermanX .Superman. )                                                                                    
(NPB~sister~2~2 YourSupermanPRP$ sisterSupermanNN /SupermanPUNC: )                                                                                                                                           

*** Splits ***                                                                                                                                                                                        
(TOP~did~1~1 (S~did~2~2 (NPB~I~1~1 I                                                                                                                                                                  
PRP ) (VP~did~3~1 did                                                                                                                                                                                 
VBD not                                                                                                                                                                                               
RB (VP~read~2~1 read                                                                                                                                                                                  
VB (NPB~article~2~2 the                                                                                                                                                                               
DT article                                                                                                                                                                                            
NN .                                                                                                                                                                                                  
PUNC. ) ) ) ) )                                                                                                                                                                                       
(TOP Source                                                                                                                                                                                           
NN http://www.alwatan.com.sa/daily/2007-01-31/first_page/first_page01.htm                                                                                                                             
X .                                                                                                                                                                                                   
. )
(NPB~sister~2~2 Your                                                                                                                                                                                  
PRP$ sister                                                                                                                                                                                           
NN /
PUNC: ) 
like image 200
Rodrigo López Avatar answered Sep 18 '22 23:09

Rodrigo López


You should be able to use a negative lookbehind with a regex. This would need a bigger sample of inputs to be sure, but seems to work for your two cases:

    String pattern = "(?<![\\:\\/])\\/";

    String s1 = "(TOP Source/NN http://www.alwatan.com.sa/daily/2007-01-31/first_page/first_page01.htm/X ./. )";
    List<String> a = (List<String>) Arrays.asList(s1.split(pattern));

    System.out.println("first case:");
    System.out.println(a.stream().map(i->i.toString()).collect(Collectors.joining(",\n")));
    System.out.println("\n");

    String s2 = "(NPB~sister~2~2 Your/PRP$ sister/NN //PUNC: )";
    a = (List<String>) Arrays.asList(s2.split(pattern));
    System.out.println("second case");
    System.out.println(a.stream().map(i->i.toString()).collect(Collectors.joining(",\n")));

This outputs:

first case:
(TOP Source,
NN http://www.alwatan.com.sa,
daily,
2007-01-31,
first_page,
first_page01.htm,
X .,
. )


second case
(NPB~sister~2~2 Your,
PRP$ sister,
NN ,
/PUNC: )
like image 36
ncoronges Avatar answered Sep 18 '22 23:09

ncoronges