I want to creating regex to remove some matching string, the string is phone number
Example user input phone number like this:
+jfalkjfkl saj f62 81 7876 asdadad30 asasda36
then output will be like this:
628178763036
at the moment with my current regex ^[\+\sa-zA-Z]+ it can select the part +jfalkjfkl saj f
What is the regex so it also can select the space bewteen number?
e.g:
62(select the space here)81, 81(select the space here)7876
I don't know what language you plan on using this in, but you can replace this pattern:
[^\d]+, with an empty string should accomplish this. It'll remove everything that's not a number.
Using PCRE regexes, you should be able to simply remove anything matching \D+. Example:
echo "+jfalkjfkl saj f62 81 7876 asdadad30 asasda36" | perl -pe 's/\D+//g'
prints:
628178763036
It would appear that you need two operations:
Remove everything that is neither a blank nor a digit:
s/[^ \d]//g;
Remove all extra blanks:
s/ +/ /g;
If you need to remove leading and trailing blanks too:
s/^ //;
s/ $//;
(after the replace multiple blanks with a single blank).
You can use \s to represent more space-like characters than just a blank.
Use a look-behind and a look-ahead to assert that digits must precede/follow the space(s):
(?<=\d) +(?=\d)
The entire regex matches the spaces, so no need to reference groups in your replacement, just replace with a blank.
If you make a replace you can reconstruct the phone number with the space between numbers:
search: \D*(\d+)\D*?(\s?)
replace: $1$2
Related
my character set is
-68,-79,-72,-70,-71,-71,-71,-71,-72,-73,R2,0000feaa-0000-1000-8000-00805f9b34fb
I want like
-68 -79 -73
and my regular expression is
[-][0-9]{2}[^0-9]
and result like
-68, -79,
I want to exclude comma in my character set
how can I solve my problem
Thank you for your help
Based on your regex and your results, I assume you are finding multiple matches and then putting spaces between each match. Let me break down what your regex is doing:
[-] matches the negative sign
[0-9]{2} matches two digits
[^0-9] matches any non-digit character, including a comma. So the commas are part of your match
If you want to exclude the commas from your match, but still assert that they are there, you need to use a positive lookahead. This is done like so:
[-][0-9]{2}(?=[^0-9])
Already said this in the comments but will post answer just for the sake of completion.
The solution to this isn't exactly regex. It's the replace function of whatever tool you're using. All you have to do is replace the , by a (space).
For example, in python .replace(',', ' ') is sufficient
which language are you using?
For example:
sed
echo "-34,-35,-34" | sed 's/,/ /g'
awk
echo "-34,-35,-34" | awk '{gsub(/,/, " ", $0); print $0}'
I would like to write a regex in Perl which will remove everything after the last comma in a string. I know the substring after the last comma is a number or some other substring, so no commas there.
Example: some\string,/doesnt-really.metter,5.
I would like the regex to remove the last comma and the 5 so the output would be: some\string,/doesnt-really.metter
I am not allowed to use any additional module only with regex. So which regex should I use?
Another example:
string_with,,,,,_no_point,some_string => string_with,,,,,_no_point
If the comma is always followed by one or more digits, you can use: s/,\d+$//. More generally, use s/,[^,]*$// (match a comma followed by zero or more non-comma characters followed by end-of-string).
This Regex captures everything before the last ,.
(.*),[^,]*$
perl -n -e 'chomp; s/(.+,)/$1/g; print "$_\n";' inputfile.txt
Just run this command directly on terminal, the regex just selects all text which comes before last comma).
I am trying to craft a regular expression that will match all characters after (but not including) the first space in a string.
Input text:
foo bar bacon
Desired match:
bar bacon
The closest thing I've found so far is:
\s(.*)
However, this matches the first space in addition to "bar bacon", which is undesirable. Any help is appreciated.
You can use a positive lookbehind:
(?<=\s).*
(demo)
Although it looks like you've already put a capturing group around .* in your current regex, so you could just try grabbing that.
I'd prefer to use [[:blank:]] for it as it doesn't match newlines just in case we're targetting mutli's. And it's also compatible to those not supporting \s.
(?<=[[:blank:]]).*
You don't need look behind.
my $str = 'now is the time';
# Non-greedily match up to the first space, and then get everything after in a group.
$str =~ /^.*? +(.+)/;
my $right_of_space = $1; # Keep what is in the group in parens
print "[$right_of_space]\n";
You can also try this
(?s)(?<=\S*\s+).*
or
(?s)\S*\s+(.*)//group 1 has your match
With (?s) . would also match newlines
In perl I want to substitute any character not [A-Z]i or [0-9] and replace it with "_" but only if this non alphanumerical character occurs between two alphanumerical characters. I do not want to touch non-alphanumericals at the beginning or end of the string.
I know enough regex to replace them, just not to only replace ones in the middle of the string.
s/(\p{Alnum})\P{Alnum}(\p{Alnum})/${1}_${2}/g;
Of course that would hurt your chanches with "#A#B%C", so you might use a look-arounds:
s/(?<=\p{Alnum})\P{Alnum}(?=\p{Alnum})/_/g;
That way you isolate it to just the non "alnum" character.
Or you could use the "keep flag", as well and get the same thing done.
s/\p{Alnum}\K\P{Alnum}(?=\p{Alnum})/_/g;
EDIT based on input:
To not eat a newline, you could do the following:
s/\p{Alnum}\K[^\p{Alnum}\n](?=\p{Alnum})/_/g;
Try this:
my $str = 'a-2=c+a()_';
$str =~ s/(?<=[A-Z0-9])[^A-Z0-9](?=[A-Z0-9])/\1_\2/gi;
Given a string of identifiers separated by :, is it possible to construct a regular expression to extract the unique identifiers into another string, also separated by :?
How is it possible to achieve this using a regular expression? I have tried s/(:[^:])(.*)\1/$1$2/g with no luck, because the (.*) is greedy and skips to the last match of $1.
Example: a:b:c:d:c:c:x:c:c:e:e:f should give a:b:c:d:x:e:f
Note: I am coding in perl, but I would very much appreciate using a regex for this.
In .NET which supports infinite repetition inside lookbehind, you could search for
(?<=\b\1:.*)\b(\w+):?
and replace all matches with the empty string.
Perl (at least Perl 5) only supports fixed-length lookbehinds, so you can try the following (using lookahead, with a subtly different result):
\b(\w+):(?=.*\b\1:?)
If you replace that with the empty string, all previous repetitions of a duplicate entry will be removed; the last one will remain. So instead of
a:b:c:d:x:e:f
you would get
a:b:d:x:c:e:f
If that is OK, you can use
$subject =~ s/\b(\w+):(?=.*\b\1:?)//g;
Explanation:
First regex:
(?<=\b\1:.*): Check if you can match the contents of backreference no. 1, followed by a colon, somewhere before in the string.
\b(\w+):?: Match an identifier (from a word boundary to the next :), optionally followed by a colon.
Second regex:
\b(\w+):: Match an identifier and a colon.
(?=.*\b\1:?): Then check whether you can match the same identifier, optionally followed by a colon, somewhere ahead in the string.
Check out: http://www.regular-expressions.info/duplicatelines.html
Always a useful site when thinking about any regular expression.
$str = q!a:b:c:d:c:c:x:c:c:e:e:f!;
1 while($str =~ s/(:[^:]+)(.*?)\1/$1$2/g);
say $str
output :
a:b:c:d:x:e:f
here's an awk version, no need regex.
$ echo "a:b:c:d:c:c:x:c:c:e:e:f" | awk -F":" '{for(i=1;i<=NF;i++)if($i in a){continue}else{a[$i];printf $i}}'
abcdxef
split the fields on ":", go through the splitted fields, store the elements in an array. check for existence and if exists, skip. Else print them out. you can translate this easily into Perl code.
If the identifiers are sorted, you may be able to do it using lookahead/lookbehind. If they aren't, then this is beyond the computational power of a regex. Now, just because it's impossible with formal regex doesn't mean it's impossible if you use some perl specific regex feature, but if you want to keep your regexes portable you need to describe this string in a language that supports variables.