I take this (?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*\. (?:jpg|gif|png))(?:\?([^#]*))?(?:#(.*))? regular expression from this answer. if i use this in my below program to match the url means i'm getting compiler error .
This is my code:
public static void main(String[] args) {
String url="http://justfuckinggoogleit.com/bart.gif";
matchesImageUrl(url);
}
public static void matchesImageUrl(String url){
Pattern imagePattern=Pattern.compile("(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*\. (?:jpg|gif|png))(?:\?([^#]*))?(?:#(.*))?");
if(imagePattern.matcher(url).matches()){
System.out.println("image matches with the pattern" + url);
}
else{
System.out.println("image does not matches with the pattern");
}
}
You need to escape twice.
So replace \ with \\.
See it work
The problem you have is that the backslash characters () in your regex are escape characters for Java, so it sees \. and \? and thinks your trying to escape a . and a ? - hence the compilation error that you're probably seeing talking about 'Invalid escape characters'.
To fix this, you need to escape the backslashes with their own backslashes. you get:
\\. and \\?
or, in full form:
(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*\\. (?:jpg|gif|png))(?:\\?([^#]*))?(?:#(.*))?
Related
I would like to escape non-alphanumeric characters occurring in a string as follows:
Say, the original string is: "test_", I would like to transform as "test\_".
In order to do this, one approach I can take by scanning the original string, and constructing a new string and while a non-alphanumeric character is found, append a '\' in front of this character.
But I am wondering if there is any cleaner approach to do the same using regular expression.
You can use the replaceable parameter as shown below:
public class Main {
public static void main(String[] args) {
String s = "test_";
s = s.replaceAll("[^\\p{Alnum}]", "\\\\$0");
System.out.println(s);
}
}
Output:
test\_
Notes:
$0 represents the string matched by the complete regex pattern, [^\\p{Alnum}].
\p{Alnum} specifies alphanumeric character and ^ inside [] is used to negate the pattern. Learn more about patterns from the documentation.
Notice the extra pair of \\ which is to escape \ that has been used to escape \.
So for my app in Android Studio I want to replace the following:
String card = cards.get(count).getCard();
if (card.contains("{Player1}")) {
String replacedCard = card.replaceAll("{Player1}", "Poep");
}
An example of String card can be: {Player1} switch drinks with the person next to you.
Somehow I can't use {} for the replacing. With the { it says: "Dangling metacharacter". Screenshot: https://prnt.sc/s2bbl8
Is there a solution for this?
the first Argument of replaceAll is a String that is parsed to a regalar Expression (regEx). The braces { } are special reserved meta characters to express something within the regular expression. To match them as normal characters, you need to escape them with a leading backslash \ and because the backslash is also a special character you need to escape itself with an additional backslash:
String replacedCard = card.replaceAll("\\{Player1\\}", "Poep");
Both { } are reserved regex characters. Since the replaceAll() function takes in a regex parameter, you have to explicitly state that { and } are part of your actual string. You can do this by prefixing them with the escape character: \. But because the escape character is also a reserved character, you need to escape it too.
Here's the correct way to write your code:
String card = cards.get(count).getCard();
if (card.contains("{Player1}")) {
String replacedCard = card.replaceAll("\\{Player1\\}", "Poep");
}
You need to escape the initial { with \. I.e;
String card = "{Player1}";
if (card.contains("{Player1}")) {
String replacedCard = card.replaceAll("\\{Player1}", "Poep");
System.out.println("replace: " + replacedCard);
}
The method String.replaceAll expects a regular expression. The other answers already give a solution for this. However, if you don't need regular expressions, then you can also use String.replace:
String replacedCard = card.replace("{Player1}", "Poep");
Since the input value of the replaceAll method expects a regex, you need to escape the curly brackets with a backslash. The curly brackets are special characters in the context of regular expressions.
In Java a backslash in a regex is accomplished by a double backslash \\ (see https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html for reference).
So you would need to adjust the line like so:
String replacedCard = card.replaceAll("\\{Player1\\}", "Poep");
{} are special characters for Regular Expressions. replaceAll method takes as first parameter a Regular Expressions, so if you want also to replace the curly brackets you have to skip them with \\ , as follow:
String card = cards.get(count).getCard();
if (card.contains("{Player1}")) {
String replacedCard = card.replaceAll("\\{Player1}", "Poep");
}
How to macth a backslah (\) in java regular expression? I hava some sript to matching all latex tag In some file but it didnt work.
public class TestMatchTag {
public static void main(String[] args) {
String tag = "\begin";
if (Pattern.matches("\\\\[a-z]+", tag)) {
System.out.println("MATCH");
}
}
}
Replace String tag = "\begin"; with String tag = "\\begin";. The regex is valid, but your input string needs to escape \ character.
Try this,
Pattern.matches("[\\a-z]+", tag)
You need another backslash to escape the "\" in "\begin", change it to "\begin", otherwise the "\b" in your "\begin" will be considered as one character.
This should work...
Pattern.matches("\\[a-z]+", tag);
[a-z] allows any character between a-z more than once and \\ allows "\" once.
you can validate your expression online here
I need to delete all tokens that are started with \ and followed by any characters.
I created such a pattern:
input.replaceAll("\\[a-zA-Z0-9]*", "");
But it doesn't work because it doesn't delete \rad from string 5 4\rad.
EDIT:
public static void main(String[] args)
{
String input="Wolf 3 3\4par";
String replaceAll = input.replaceAll("\\\\[a-zA-Z0-9]*", "");
System.out.println("replaceAll=" + replaceAll);
}
Thank you!
The \ is special both in string literals and in regular expressions. To put an actual \ in a regular expression, you have to escape it twice. You also have to assign the result somewhere, which it wasn't clear from your question you were doing. So:
input = input.replaceAll("\\\\[a-zA-Z0-9]*", "");
Complete example: Live Copy
import java.util.*;
public class Temp {
public static void main(String[] args) {
String input = "4 5 \\rad";
input = input.replaceAll("\\\\[a-zA-Z0-9]*", "");
System.out.println(input);
}
}
Output:
4 5
To create \ literal in regex you need to pass \\ to regex engine. But to create \ literal in String you also have to escape it so you need to write it as "\\".
\ literal in regex engine
\\ regex pattern
"\\\\" String representing regex pattern
Now you are using one \ in your regex pattern regex engine sees it as \[ which escapes [ making it simple literal.
Try this way
input.replaceAll("\\\\[a-zA-Z0-9]*", "");
From
Sorry, but my String is exactly 5 4\rad. Indeed how to delete \rad? – Volodymyr Levytskyi
Try
String k= "5 4\rad";
System.out.println(k.replaceAll("\r\\w*", ""));
Output
5 4
Trying to extract strings that are wrapped in double brackets. For example [[this is one token]] that should be matched. To make things more elegant, there should be an escape sequence so that double bracketed items like \[[this escaped token\]] don't get matched.
The pattern [^\\\\]([\\[]{2}.+[^\\\\][\\]]{2}) with "group 1" to extract the token is close, but there are situations where it doesn't work. The problem seems to be that the first "not" statement is being evaluated as "anything except a backslash". The problem is, "anything" is not including "nothing". So, what would make this pattern match "nothing or any character other than a backslash"?
Here is a unit test to show the desired behavior:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import junit.framework.TestCase;
public class RegexSpike extends TestCase {
private String regex;
private Pattern pattern;
private Matcher matcher;
#Override
protected void setUp() throws Exception {
super.setUp();
regex = "[^\\\\]([\\[]{2}.+[^\\\\][\\]]{2})";
pattern = Pattern.compile(regex);
}
private String runRegex(String testString) {
matcher = pattern.matcher(testString);
return matcher.find() ? matcher.group(1) : "NOT FOUND";
}
public void testBeginsWithTag_Passes() {
assertEquals("[[should work]]", runRegex("[[should work]]"));
}
public void testBeginsWithSpaces_Passes() {
assertEquals("[[should work]]", runRegex(" [[should work]]"));
}
public void testBeginsWithChars_Passes() {
assertEquals("[[should work]]", runRegex("anything here[[should
work]]"));
}
public void testEndsWithChars_Passes() {
assertEquals("[[should work]]", runRegex("[[should
work]]with anything here"));
}
public void testBeginsAndEndsWithChars_Passes() {
assertEquals("[[should work]]", runRegex("anything here[[should
work]]and anything here"));
}
public void testFirstBracketsEscaped_Fails() {
assertEquals("NOT FOUND", runRegex("\\[[should NOT work]]"));
}
public void testSingleBrackets_Fails() {
assertEquals("NOT FOUND", runRegex("[should NOT work]"));
}
public void testSecondBracketsEscaped_Fails() {
assertEquals("NOT FOUND", runRegex("[[should NOT work\\]]"));
}
}
You can simply use (^|[^\\]), which will either match the beginning of a string (provided you set the MULTILINE mode on your regex) or a single character that is not a backslash (including spaces, newlines, etc.).
You'll also want to replace .+ with .+?, because otherwise a string such as "[[one]] and [[two]]" will be seen as a single match, where "one]] and [[two" is considered to be between brackets.
A third point is that you do not have to wrap a single character (even escaped ones such as \[ or \]) in a character class with [].
So that would make the following regex (pardon me removing the double-escapedness for clarity):
(^|[^\\])(\[{2}.+?[^\\]\]{2})
(Also note that you cannot escape the escape character with your regex. Two slashes before a [ will not be parsed as a single (escaped) slash, but will indicate a single (unescaped) slash and an escaped bracket.)
You want a "zero-width negative lookbehind assertion", which is (?<!expr). Try:
(?<!\\\\)([\\[]{2}.+[^\\\\][\\]]{2})
Actually, this can be simplified and made more general by cutting out some of those unnecessary brackets, and adding a negative lookbehind for the closing bracket, too. (Your version also will fail if you have an escaped bracket in the middle of the string, like [[text\]]moretext]]).
(?<!\\\\)(\\[{2}.*?(?<!\\\\)\\]{2})
What should happen with this string? (Actual string content, not a Java literal.)
foo\\[[blah]]bar
What I'm asking is whether you're supporting escaped backslashes. If you are, the lookbehind won't work. Instead of looking for a single backslash, you would have to check for on odd but unknown number of them, and Java lookbehinds can't be open-ended like that. Also, what about escaped brackets inside a token--is this valid?
foo[[blah\]]]bar
In any case, I suggest you come at the backslash problem from the other direction: match any number of escaped characters (i.e. backslash plus anything) immediately preceding the first bracket as part of the token. Inside the token, match any number of characters other than square brackets or backslashes, or any number of escaped characters. Here's the actual regex:
(?<!\\)(?:\\.)*+\[\[((?:[^\[\]\\]++|\\.)*+)\]\]
...and here it is as a Java string literal:
"(?<!\\\\)(?:\\\\.)*+\\[\\[((?:[^\\[\\]\\\\]++|\\\\.)*+)\\]\\]"