How can I replace all matches with preg_replace only when not inside quotes? - preg-replace

can someone help me to solve this problem?
I have this string:
$app.url = $cfg.url ? $cfg.url : 'domain.ext'
What I need is convert it to this:
$app[url] = $cfg[url] ? $cfg[url] : 'domain.ext'
What I try:
$input = $app.url = $cfg.url ? $cfg.url : 'domain.ext';
preg_replace('/(\.)(\w+)/', '[$2]', $input);
The result of above:
$app[url] = $cfg[url] ? $cfg[url] : 'domain[ext]'
I also try with:
$input = $app.url = $cfg.url ? $cfg.url : 'domain.ext';
preg_replace('/(!\')(\.)(\w+)/', '[$2]', $input);
Result above:
$app.url = $cfg.url ? $cfg.url : 'domain.ext'
But no satisfactory result.
Thanks in advance.

You can use
'[^\\']*(?:\\.[^\\']*)*'(*SKIP)(*F)|\.(\w+)
See the regex demo.
In PHP, you can use
preg_replace("/'[^\\\\']*(?:\\\\.[^\\\\']*)*'(*SKIP)(*F)|\.(\w+)/s", '[$1]', $input)
Pattern details
'[^\\']*(?:\\.[^\\']*)*'(*SKIP)(*F) - a single quoted string literal pattern:
' - a ' char
[^\\']* - zero or more chars other than ' and \
(?:\\.[^\\']*)* - zero or more sequences of any escaped char and then zero or more chars other than \ and '
' - a ' char
(*SKIP)(*F) - fails the match and triggers next match search from the failure position
| - or
\.(\w+) - a dot and then one or more word chars captured into Group 1.

Related

Matlab: Select a variable name and find the corresponding value

Can somebody explain me how i get some specific values after the = sign? The input File is a .subvar file format.
I dont know how to jump in the right row and column to get the value. Do you have a matlab tutorial link for such a problem.
I need for example two specific values (after the = sign):
The value of $_Wk1_lr_m and $_Wk1_voll_m
!file.version=1.543!
! Testautomatisch
subvargroup.begin ($G_Wk1)
subvar( $_Wk1_lr_C_x, str = ' 0.019 ' )
subvar( $_Wk1_lr_m, str = ' 15601 ' ) ! [kg] lr
subvar( $_Wk1_lr_C_y, str = '-0.007 ' )
subvar( $_Wk1_lr_C_z, str = ' 1.644 ' )
subvar( $_Wk1_voll_m, str = ' 33690 ' ) ! [kg] voll
subvargroup.end ($G_Wk1)
What are the first steps to get the right row and the right column? Thank you and stay at home :)
read the file line by line, match the line format and extract the values using regular expression regexp
fid=fopen('mydata.subvars','rt');
res=struct;
while(~feof(fid))
line=fgetl(fid);
if(regexp(line,'^\s*subvar\(','once'))
val=regexp(line,'\$_(\w+),\s*str\s*=\s*''\s*([0-9.-]+)\s*','tokens');
if(length([val{:}])==2)
res.(val{1}{1})=str2num(val{1}{2});
end
end
end
fclose(fid);
here is the result
>> res
res =
Wk1_lr_C_x: 0.0190
Wk1_lr_m: 15601
Wk1_lr_C_y: -0.0070
Wk1_lr_C_z: 1.6440
Wk1_voll_m: 33690

Alternative of ChrW function

Is there any alternative function/solution of the ChrW() which accepts value not in range is -32768–65535 like for character code 􀂇 which leads to "􀂇". Using ChrW() gives error
"Invalid procedure call or argument"
So I want an alternative solution to convert the charactercode to the actual character.
Code:
Function HTMLDecode(sText)
Dim regEx
Dim matches
Dim match
sText = Replace(sText, """, Chr(34))
sText = Replace(sText, "<" , Chr(60))
sText = Replace(sText, ">" , Chr(62))
sText = Replace(sText, "&" , Chr(38))
sText = Replace(sText, " ", Chr(32))
Set regEx= New RegExp
With regEx
.Pattern = "&#(\d+);" 'Match html unicode escapes
.Global = True
End With
Set matches = regEx.Execute(sText)
'Iterate over matches
For Each match In matches
'For each unicode match, replace the whole match, with the ChrW of the digits.
sText = Replace(sText, match.Value, ChrW(match.SubMatches(0)))
Next
HTMLDecode = sText
End Function
' https://en.wikipedia.org/wiki/UTF-16#Description
function Utf16Encode(byval unicode_code_point)
if (unicode_code_point >= 0 and unicode_code_point <= &hD7FF&) or (unicode_code_point >= &hE000& and unicode_code_point <= &hFFFF&) Then
Utf16Encode = ChrW(unicode_code_point)
else
unicode_code_point = unicode_code_point - &h10000&
Utf16Encode = ChrW(&hD800 Or (unicode_code_point \ &h400&)) & ChrW(&hDC00 Or (unicode_code_point And &h3FF&))
end if
end function
For Each match In matches
'For each unicode match, replace the whole match, with the ChrW of the digits.
sText = Replace(sText, match.Value, Utf16Encode(CLng(match.SubMatches(0))))
Next

Erlang : variable '_' is unbound

I'm trying to use "_" in Case but I'm missing some thing.
What i'm doing is :
case (Packet =:= #xmlel{name = <<"message">>, attrs = [_, {<<"type">>,<<"chat">>}], children = _}) of
true ->
?INFO_MSG("True ###### Packet ~p", [Packet]);
_ ->
?INFO_MSG("False ###### Packet ~p", [Packet])
end,
And the error is : variable '_' is unbound.
I want this variable "_" to mean in this function every thing.
Like -->
attrs = [Whatever, {<<"type">>,<<"chat">>}]
children = Whatever
How can I do it? thnx.
The problem is:
You cannot use '_' on the right of '='
You can only put it on the left of the '='
e.g.
{_,4} = {x,y} (correct)
{x,y} = {_,4} (wrong)

How can I remove <math></math> multiline sections with Perl?

How can I remove multiline sections with Perl?
I have such wiki test code:
{|
|-
| colspan="2"|
: <math>
[\underbrace{\color{Red}4,2}_{4 > 2},5,1,7] \rightarrow
[2,\underbrace{\color{OliveGreen}4,5}_{4 < 5},1,7] \rightarrow
[2,4,\underbrace{\color{Red}5,1}_{5 > 1},7] \rightarrow
[2,4,1,\underbrace{\color{OliveGreen}5,7}_{5 < 7}]
</math>
|-
|
: <math>
[\underbrace{\color{OliveGreen}2,4}_{2 < 4},1,5,{\color{Blue}7}] \rightarrow
[2,\underbrace{\color{Red}4,1}_{4 > 1},5,{\color{Blue}7}] \rightarrow
[2,1,\underbrace{\color{OliveGreen}4,5}_{4 < 5},{\color{Blue}7}]
</math>
: <math>
[\underbrace{\color{Red}2,1}_{2 > 1},4,{\color{Blue}5},{\color{Blue}7}] \rightarrow
[1,\underbrace{\color{OliveGreen}2,4}_{2 < 4},{\color{Blue}5},{\color{Blue}7}]
</math>
: <math>
[\underbrace{\color{OliveGreen}1,2}_{1 < 2},{\color{Blue}4},{\color{Blue}5},{\color{Blue}7}]
</math>
|}
And I want to remove from this code all how to do it? I have done such code:
cat math-text.txt | perl -e 'while(<>) { s/<math>.+?<\/math>//gs; print $_; }'
It is not works but should since documentation explains that . will much new lines. How to do it?
The following is a python script which I use to extract all the mathematical formula from wikipedia dumps. Rather than using a multi-line regexp it scans for occurrences of <math> </math> and uses the position on the line to work out where the actual position on the line is and uses a finite state machine to find the actual equations, basically with two states determined by inEqn. It does a few other things like find the title and name space and attributes in the maths tags.
As dumps are in the order of 100MB using a line by line approach may well end up being more efficient than multi-line regexps.
import sys
import re
titleRE = re.compile('<title>(.*)</title>')
nsRE = re.compile('<ns>(.*)</ns>')
mathRE = re.compile('</?math(.*?)>')
pageEndRE = re.compile('</page>')
title =""
attr = ""
ns = -1
inEqn = 0
for line in sys.stdin:
m = titleRE.search(line)
if m :
title = m.group(1)
expression = ""
inEqn = 0
m = nsRE.search(line)
if m :
ns = m.group(1)
start = 0
pos = 0
m = mathRE.search(line,pos)
while m :
if m.group().startswith('<math'):
attr = m.group(1)
start = m.end()
pos = start
expression = ""
inEqn = 1
if m.group() == '</math>' :
end = m.start()
expression = ' '.join([expression,line[start:end]])
print title,'\t',attr,'\t',expression.lstrip().replace('<','<').replace('>','>').replace('&','&')
pos = m.end()
expression = ""
start = 0
inEqn = 0
m = mathRE.search(line,pos)
if start > 0 :
expression = line[start:].rstrip()
elif inEqn :
expression = ' '.join([expression,line.rstrip()])
Another option might be to consider an xml parser. A SAX or DOM based parser would be able to find the equations. This might be worth considering if you want to do more sophisticated analysis of the wiki-text.

genstrings does not work with macro for NSLocalizedString

I would like to shorten "NSLocalizedString" to "_" so I'm using macro
_(x) NSLocalizedString(#x, #__FILE__)
.
But now, when I want to generate strings for localization with
find . -name \*.m | xargs genstrings
it generates nothing.
Any help?
You can tell genstrings to look for a different function by using the '-s' argument:
genstring -s MyFunctionName ....
However, MyFunctionName must follow the same naming and argument conventions as one of the built in NSLocalizeString macros.
In your case, you can not just specify the string key, you must also specify the documentation string. In fact, you should never generate a strings file without both the string and documentation. There are many languages where the actual phrase or word will depend on context. German is a great example where a car is "das auto" and more than one is "die autos". There are many more examples that include changes for gender, number, time, question versus statement, and yes versus no. The documentation string helps your translator figure out what translation to use.
In addition, the best practice is to use a key that is different from the native language word. That says use NSLocalizedStringWithDefaultValue(key, table, bundle, val, comment).
You can specify nil for the table and [NSBundle mainBundle] for the bundle argument.
You can wrap this in a shorthand, but you still have to follow the StringWithDefaultValue name and the arguments for genstrings to work.
I strongly recommend you look at the WWDC 2012 session on Localization Tips and Tricks.
Maurice
You can use the -s option of genstrings. From the man page :
-s routine
Substitutes routine for NSLocalizedString. For example, -s MyLocalString will catch calls to MyLocalString and MyLocalStringFromTable.
So I think you could try :
genstrings -s _
I had the same problem when my NSLocalizedString macro was taking 1 argument instead of 2 like genstrings expects, so i wrote i python script that does the job.
the first argument for the script is the macro name and the second is the path to your project.
import fnmatch
import os
from xml.dom import minidom
function = sys.argv[1]
rootdir = sys.argv[2]
# Generate strings from .m files
files = []
for root, dirnames, filenames in os.walk(rootdir):
for filename in fnmatch.filter(filenames, '*.m'):
files.append(os.path.join(root, filename))
strings = []
for file in files:
lineNumber = 0
for line in open(file):
lineNumber += 1
index = line.find(function)
if (index != -1):
callStr = line[index:]
index = callStr.find('#')
if (index == -1):
print 'call with a variable/macro. file: ' + file + ' line: %d' % lineNumber
else:
callStr = callStr[index+1:]
index = callStr.find('")')
callStr = callStr[:index+1]
if callStr not in strings:
strings.append(callStr)
# Write strings to file
f = open('Localizable.strings', 'w+')
for string in strings:
f.write(string + ' = ' + string + ';\n\n')
f.close()
I have improved Or Arbel's script to include the cases where there's multiple macro-calls on a single line:
import fnmatch
import os
from xml.dom import minidom
import sys
function = sys.argv[1]
rootdir = sys.argv[2]
# Generate strings from .m files
files = []
for root, dirnames, filenames in os.walk(rootdir):
for filename in fnmatch.filter(filenames, '*.m'):
files.append(os.path.join(root, filename))
strings = []
for file in files:
lineNumber = 0
for line in open(file):
lineNumber += 1
index = line.find(function)
startIndex = 0
while (index != -1):
startIndex = index+1
callStr = line[index:]
index = callStr.find('#')
if (index == -1):
print 'call with a variable/macro. file: ' + file + ' line: %d' % lineNumber
else:
callStr = callStr[index+1:]
index = callStr.find('")')
callStr = callStr[:index+1]
if callStr not in strings:
strings.append(callStr)
index = line.find(function, startIndex)
# Write strings to file
f = open('Localizable.strings', 'w+')
for string in strings:
f.write(string + ' = ' + string + ';\n\n')
f.close()