PHP do 2 preg_replace in link tag - preg-replace

I am trying to make a multi preg_replace, not sure if thats the correct function.
I want this outcome
[link]www.mynewhomepage.com(My new homepage)[/link]
to become <a href=mynewhomepage.com>My New homepage</a>
I have made this code, which dosent give me what i want
$string = 'i have made a new homepage visit [link]http://myhomepage.dk(My New homepage)[/link]';
$find = array('#\[link\](.+)\[\/link\]#iUs', '#\((.+)\)#iUs');
$replace = array('<a href=$1>', '</a>');
$result = preg_replace($find, $replace, $string);
echo $result;
And it give me this outcome: http://myhomepage.dk>
Can anyone guide me or help me in the right direction of what i am doing wrong? :)
Thanks and happy summer for you :)

This should work:
\[link\](.*?)\((.*)\)\[\/link\]
https://regexr.com/3sc23
It basically matches up to first left parenthesis and also from last parenthesis to the end. Then you put these pieces into capturing groups for referencing them later.
Use $2 as substitution
About your original question, your solution had these problems:
For first replacement we should use <a href="$1. Note that we use " at the beginning of the link but for the moment we do not add it at the end. That way, the nest regexp will be easier.
Then, on the second regexp we should add "> at the beginning in order to close the tag. Also you were not using the captured group at all. That would be the replacement: ">$1</a>
That is, change this line:
$replace = array('<a href=$1>', '</a>');
to this:
$replace = array('$1');

Related

How to remove quotes in my product description string?

I'm using OSCommerce for my online store and I'm currently optimizing my product page for rich snippets.
Some of my Google Indexed pages are being marked as "Failed" by Google due to double quotes in the description field.
I'm using an existing code which strips the html coding and truncates anything after 197 characters.
<?php echo substr(trim(preg_replace('/\s\s+/', ' ', strip_tags($product_info['products_description']))), 0, 197); ?>
How can I include the removal of quotes in that code so that the following string:
<strong>This product is the perfect "fit"</strong>
becomes:
This product is the perfect fit
Happened with me, try to use:
tep_output_string($product_info['products_description']))
" becomes "
We can try using preg_replace_callback here:
$input = "SOME TEXT HERE <strong>This product is the perfect \"fit\"</strong> SOME MORE TEXT HERE";
$output = preg_replace_callback(
"/<([^>]+)>(.*?)<\/\\1>/",
function($m) {
return str_replace("\"", "", $m[2]);
},
$input);
echo $output;
This prints:
SOME TEXT HERE This product is the perfect fit SOME MORE TEXT HERE
The regex pattern used does the following:
<([^>]+)> match an opening HTML tag, and capture the tag name
(.*?) then match and capture the content inside the tag
<\/\\1> finally match the same closing tag
Then, we use a callback function which does an additional replacement to strip off all double quotes.
Note that in general using regex against HTML is bad practice. But, if your text only has single level/occasional HTML tags, then the solution I gave above might be viable.

Powershell confusion about Variable

I am confused regarding variables.
I have code, where I have the following line:
$search = $Name.SelectedItem.Split('-')[$($Name.SelectedItem.Split('-').Count-1)]+'*'
This line does nothing else, as split up a selected item (I am working with a Dropdownbox) and transfers it to $search.
The funny thing is, it does exactly that, what I want it to do.
When I type $search, the result can be for example:
Rue de Rivoli*
When I continue in the code and use $search through several arrays, for some reason, it does not function, because it does not find anything in a foreach loop. I have no error message and even the Rue de Rivoli* existing in one of the arrays, it does not find anything.
When I replace the above code and give directly the name to the variable $search, as seen below
$search = 'Rue de Rivoli*'
my search in the array works.
What am I missing here? I am doing something wrong, but I do not know what it is, can someone help me please to understand?
Thank you very much,
Mike
As requested, here more of the code. It is a lot to deal with, that is why I shorten it.
Clear-Host
$search = $CreateNewUserFormDropDownBoxLocation.SelectedItem.Split('-')[$($CreateNewUserFormDropDownBoxLocation.SelectedItem.Split('-').Count-1)]+'*'
#$search = 'Rue de Rivoli*'
$AllLocations = (get-variable -Include USPennsylvaniaAve, USSixthStreet, USRodeoDrive, USOneMicrosoftWay,`
USNorthTantauAvenue, USMarketStreet, USMainStreet, USEmilyDrive,`
USCalle8, USBroadway, US18thStreetNW, UKOxfordStreet, UKDowningStreet,`
UKBondStreet, FRRuedeRivoli, FRChampsElysees, CHBahnhofstrasse,`
CA17thAvenue) | ? {$_.value -is [array]}
Foreach ($Array in $AllLocations)
{
if ($array.value -like $search)
{break}
}
$result = "`$$($array.name)"
$result
This is about to become a function and does nothing else, as from the selecteditem, it takes it apart and add's the * behind it, so I can search
for a name with a wildcard.
I have several arrays and therefore I included only the necessary ones. Next step is to loop through the arrays and as soon as it found the item, it stops and gives the result to result.
This is my test code and it runs and does what I want, besides the line after Clear-Host. The code is correctly resolved and added to $search but does not work.
Below that code of line, I have my cheat line, where I add directly the correct result to the variable and it works fine.
As commented, this should solve the problem.
(I'm adding this as answer too, so the OP can accept it. Otherwise this question will remain seemingly unsolved)
When hardcoding the search string $search = 'Rue de Rivoli*' works, but using a Split() to get the search string does not, then usually the string you obtain using the split is surrounded by whitespace characters. If you leave these in, the string will appear to look just fine, but when using as comparison it won't work.
If for instance the complete $CreateNewUserFormDropDownBoxLocation.SelectedItem string is:
"François Exemple - Rue de Rivoli"
Then, using $CreateNewUserFormDropDownBoxLocation.SelectedItem.Split("-")[-1] will return:
" Rue de Rivoli"
Note the space in front.
By simply performing a Trim() you will get rid of that space.
The line therefore should be:
$search = ($CreateNewUserFormDropDownBoxLocation.SelectedItem.Split('-')[-1]).Trim() + '*'

Powershell indent here-string

Does anybody know if it is possible to intend a here-string. Actually I've to write:
$someString = #"
First line
second line
"#
This becomes very ugly if you define a here-string on a deeper indentation level, because the ending "# must be the first character on the line. Additionally somebody might "fix" the missing indentation and break the script ...
Is it possible to define a here-string like:
$someString = #"
First line
second line
"#
Thx
The closing "# must be at the start of the line.
I agree with you that this can make the script file harder to read, but it is the rule, and there is no way around it as far as I know.
You can find a uservoice entry here, and you should vote for it if you feel this is important to you. It does not look like a priority at the moment, with only 3 votes, but the more votes, the higher the priority for the powershell team to look into it.
Late answer (technically "workaround"), I know, but this is currently one of the first search results for "PowerShell here-string indentation".
This becomes very ugly if you define a here-string on a deeper indentation level
I agree. For those of us concerned with the aesthetics of the resulting code, I found the following workaround on this TechNet question.
It's definitely not a here-string (especially since you must still escape embedded quotes), but at least for many multi-line use-cases, it will serve the same purpose, and allow you to keep indenting at the same level as the rest of the code-block:
$somestring = (
"First line",
"Second line"
) -join "`r`n"
To expand upon #NotTheDr01ds's answer, you can make it even more aesthetically pleasing by excluding commas after each item. So long as each item in the array is on its own line:
$HTML = #(
"<h1>OIDC Services are <font style='color:green'>Online</font></h1>"
"<br/><p>Your identity: <ul><li>Username: $($Context.User.Identity.Name)</li></ul></p>"
"<br/><p>Troubleshooting: <ul><li><a href='/restart-service'>Restart Service</a></li></ul></p>"
) -Join "`n"

Splitting a variable and putting into an array

I have a string like this <name>sekar</name>. I want to split this string (i am using perl) and take out only sekar, and push it into an array while leaving other stuff.
I know how to push into an array, but struck with the splitting part.
Does any one have any idea of doing this?
push #output, $1 if m|<name>(\w*)</name>|;
Try this:
my($name) = $string =~ m|<name>(.*)</name>|;
From perldoc perlop:
If the "/g" option is not used, "m//" in list context returns a
list consisting of the subexpressions matched by the
parentheses in the pattern, i.e., ($1, $2, $3...).
Try <(("[^"]*"|'[^']*'|[^'">])*)>(\w+)<\/\1>. Should work, when I get home I'll test it. The idea is that the first capture group finds the contents within a <> and its nested capture group prevents a situation like <blah=">"> matching as <blah=">. The third capture group (\w+) matches the inner word. This may have to be changed depending on the format of the possibilities you can have within the <tag>content</tag>. Lastly the \1 looks back at the content of the first capture group so that this way you will find the proper closing tag.
Edit: I've tested this with perl and it works.

Reading custom values in Ebay RSS feed (XML::RSS module)

I've spent entirely way too long trying to figure this out. I'm using XML: RSS and Perl to read / parse an Ebay RSS feed. Within the <item></item> area, I see these entries:
<rx:BuyItNowPrice xmlns:rx="urn:ebay:apis:eBLBaseComponents">1395</rx:BuyItNowPrice>
<rx:CurrentPrice xmlns:rx="urn:ebay:apis:eBLBaseComponents">1255</rx:CurrentPrice>
However, I can't figure out how to grab the details during the loop. I wrote a regex to grab them:
#current_price = $item =~ m/\<rx\:CurrentPrice.*\>(\d+)\<\/rx\:CurrentPrice\>/g;
Which works if you place the above 'CurrentPrice' entry into a standalone string, but not while the script is reading through the RSS feed.
I can grab most of the information I want out of the item->description area (# bids, auction end time, BIN price, thumbnail image, etc.), but it would be nicer if I could grab the info from the feed without me having to deal with grabbing all that information manually.
How to grab custom fields from an RSS feed (short of writing regexes to parse the entire feed w/o a module)?
Here's the code I'm working with:
$my_limit = 0;
use LWP::Simple;
use XML::RSS;
$rss = XML::RSS->new();
$data = get( $mylink );
$rss->parse( $data );
$channel = $rss->{channel};
$NumItems = 0;
foreach $item (#{$rss->{'items'}}) {
if($NumItems > $my_limit){
last;
}
#current_price = $item =~ m/\<rx\:CurrentPrice.*\>(\d+)\<\/rx\:CurrentPrice\>/g;
print "$current_price[0]";
}
If you have the rss/xml document and want specific data you could use XPATH:
Perl CPAN XPATH
XPath Introduction
What is the way in which "it doesn't work" from an RSS feed? Do you mean no matches when there should be matches? Or one match where there should be several matches?
One thing that jumps out at me about your regular expression is that you use .*, which can sometimes be greedier than you want. That is, if $item contained the expression
<rx:BuyItNowPrice xmlns:rx="urn:...nts">1395</rx:BuyItNowPrice>
<rx:CurrentPrice xmlns:rx="urn:...nts">1255</rx:CurrentPrice>
<rx:BuyItNowPrice xmlns:rx="urn:...nts">1395</rx:BuyItNowPrice>
<rx:SomeMoreStuff xmlns:rx="urn:...nts">zzz</rx:BuyItNowPrice>
<rx:CurrentPrice xmlns:rx="urn:...nts">1255</rx:CurrentPrice>
then the first part of your regular expression (\<rx\:CurrentPrice.*\>) will wind up matching everything on lines 2, 3, and 4, plus the first part of line 5 (up to the >). Instead, you might want to use the regular expression1
m/\<rx:CurrentPrice[^>]*>(\d+)\<\/rx:CurrentPrice\>/
which will only match up to the closing </rx:CurrentPrice> tag after a single instance of an opening <rx:CurrentPrice> tag.
1 The other obvious answer is that you really don't want to use a regular expression at all, that regular expressions are inferior tools for parsing XML compared to customized parsing modules, and that all the special cases you will have to deal with using regular expressions will eventually render you unconscious from having repeatedly beaten your head against your desk. See Salgar's answer, for example.