Why differs German and Swiss Number to String Conversion? - powershell

I'm just trying to convert a float I read from Exel to a string with using a comma as decimal separator and two digits behind the comma.
I try the following code
$a = 707.63790474
$l = New-Object System.Globalization.CultureInfo("de-CH")
"CH: " + $a.ToString("F2", $l)
$l = New-Object System.Globalization.CultureInfo("de-DE")
"DE: " + $a.ToString("F2", $l)
$l = New-Object System.Globalization.CultureInfo("en-US")
"US: " + $a.ToString("F2", $l)
and get
CH: 707.64
DE: 707,64
US: 707.64
But to my knowledge a comma is used as decimal separator in Switzerland, unless it is a currency cf. http://en.wikipedia.org/wiki/Decimal_mark. Do I miss something?

Type (New-Object System.Globalization.CultureInfo("de-CH")).numberFormat to get numberformatinfo for de-CH
You'll get:
CurrencyDecimalDigits : 2
CurrencyDecimalSeparator : .
IsReadOnly : False
CurrencyGroupSizes : {3}
NumberGroupSizes : {3}
PercentGroupSizes : {3}
CurrencyGroupSeparator : '
CurrencySymbol : Fr.
NaNSymbol : n. def.
CurrencyNegativePattern : 2
NumberNegativePattern : 1
PercentPositivePattern : 1
PercentNegativePattern : 1
NegativeInfinitySymbol : -unendlich
NegativeSign : -
NumberDecimalDigits : 2
NumberDecimalSeparator : .
NumberGroupSeparator : '
CurrencyPositivePattern : 2
PositiveInfinitySymbol : +unendlich
PositiveSign : +
PercentDecimalDigits : 2
PercentDecimalSeparator : .
PercentGroupSeparator : '
PercentSymbol : %
PerMilleSymbol : ‰
NativeDigits : {0, 1, 2, 3...}
DigitSubstitution : None
As you can see both NumberDecimalSeparator and CurrencyDecimalSeparator are .

No, it looks like Switzerland uses . as the decimal separator (like normal people do), so this is correct output:
http://publib.boulder.ibm.com/infocenter/forms/v3r5m1/index.jsp?topic=%2Fcom.ibm.form.designer.locales.doc%2Fi_xfdl_r_formats_de_CH.html

Related

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

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.

parsing text with Parse::RecDescent

I am trying to parse some text with Parse::RecDescent
from :
x=2 and y=2 and f=3 and (x has 3,4 or r=5 or r=6 ) and z=2
to something like :
x equal 2 and y equal 2 and f equal 3 and (( x contains 3 or x contains 4 or r equal 5 or requal 6 )) and z equal 2
other example :
input :
x= 3 and y has 5 and (z has 6 or z=3 ) and f=2
output :
x equals 3 and (( y contains 5)) and ((z has 6 or z equals 3)) and f equals 2
my question if i find a list of those operators :
has ,or
i should put "((" before the code and "))" after the code as mentioned on the example aboves
is it possible to do something like this with Parse::RecDescent ?
The grammar would look something like the following:
parse : expr EOF
expr : logic_or
# vvv Lowest precedence vvv
logic_or : <leftop: logic_and LOGIC_OR logic_and>
logic_and : <leftop: comparison LOGIC_AND comparison>
comparison : term comparison_[ $item[1] ]
comparison_ : '=' term
| HAS ident_list
|
# ^^^ Highest precedence ^^^
ident_list : <leftop: IDENT ',' IDENT>
term : '(' expr ')'
| IDENT
# Tokens
IDENT : /\w+/
LOGIC_OR : /or\b/
LOGIC_AND : /and\b/
HAS : /has\b/
EOF : /\Z/
Now you just need to add the code block to emit the desired output.
In comparison_, the LHS term is available as $arg[0].
I had to make some assumptions, so there could be errors.

Powershell function acting weird and only returns the param

[context] I'm writing an application that converts xml data to Excel, the problem is that the excel file cant have empty entry's, but the xml has. My solution is that I created timestamps that I expected to see in the XML. The function below takes care of that. He's checking if the node exists and he's checking if the expected timestamp is there.
The weird thing here is that if I want to get my return values, I only see the parameters I gave.
This is my function
function CompleteData([array]$timestamps, [array]$measurements, [xml]$xml, [int]$aantalapplicaties, [array]$datesofthemonth) {
$indexgecontroleerd = 0
for ($i = 0; $i -le $aantalapplicaties - 1; $i++) {
for ($j = 0; $j -le $datesofthemonth.Length - 1; $j++) {
$indexgecontroleerd++
$node = $xml.dashboardreport.data.chartdashlet[$j]
if (!$node.measures.measure.measure.measurement[$j] -or $node.measures.measure.measure.measurement[$j].timestamp -ne $datesofthemonth ) {
$correctTimestamps = $timestamps[0..$indexgecontroleerd - 1]
$restTimestamps = $timestamps[$indexgecontroleerd..$timestamps.Length]
$correctTimestamps += $datesofthemonth[$j]
$timestamps = $correctTimestamps + $restTimestamps
$correctemeasurements = $measurements[0..$indexgecontroleerd - 1]
$restmeasuremetns = $measurements[$indexgecontroleerd..$measurements.Length]
$correctemeasurements += "0"
$measurements = $correctemeasurements + $restmeasuremetns
}
}
}
return $measurements, $timestamps
}
It's comming from 3 different XML's so here you have the reference to the function:
$return1 = CompleteData($timestamps1, $firstRowMesOG, $xdoc, $applicationArray.Length, $allDates)
$return2 = CompleteData($timestamps2, $betweenMesOG, $xdoc2, $applicationArray.Length, $allDates)
$return3 = CompleteData($timestamps3, $LastmesOG, $xdoc3, $applicationArray.Length, $allDates)
And this is what i get as return value:
PS C:\Users\yniasr> $return3
Length : 184
LongLength : 184
Rank : 1
SyncRoot : {1517439600, 1517526000, 1517612400, 1517698800...}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 184
Length : 184
LongLength : 184
Rank : 1
SyncRoot : {840, 718, 106, 6...}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 184
xml : version="1.0" encoding="utf-8"
dashboardreport : dashboardreport
8
Length : 28
LongLength : 28
Rank : 1
SyncRoot : {1517443200, 1517529600, 1517616000, 1517702400...}
IsReadOnly : False
IsFixedSize : True
IsSynchronized : False
Count : 28
Where is my mistake? Still pretty new to powershell (version 5.1)
Calling powershell functions doesn't use parentheses and commas. Your calls should look more like this:
$return1 = CompleteData -timestamps $timestamps1 -measurements $firstRowMesOG -xml $xdoc -aantalapplicaties $applicationArray.Length -datesofthemonth $allDates

Can you explain this nested conditional expression?

I can't decipher this line of code. Could someone please translate it into if / else statements?
I understand the basic CONDITION ? VALUE_IF_TRUE : VALUE_IF_FALSE pattern, but this line seems to break that.
$type = $self->{1}{_flag} & 2 ?
$self->{2}{_flag} & 2 ? "A" : "B" :
$self->{2}{_flag} & 2 ? "B" : "C";
I think it's irresponsible to write code like that where the operator precedence is far from obvious
Using a mixture of if / else and conditional expressions it looks much clearer like this
if ( $self->{1}{_flag} & 2 ) {
$type = $self->{2}{_flag} & 2 ? "A" : "B";
}
else {
$type = $self->{2}{_flag} & 2 ? "B" : "C";
}
A couple of line breaks makes all the difference, although I've also added some parens to make it crystal clear.
$type = $self->{1}{_flag} & 2
? ( $self->{2}{_flag} & 2 ? "A" : "B" )
: ( $self->{2}{_flag} & 2 ? "B" : "C" );
That's almost as cryptic as the equivalent
$type = (qw/C x B x A/)[ $self->{1}{_flag} & 2 + $self->{2}{_flag} & 2 ];
More seriously, nesting ternary operators in the true-branch is confusing. I'd use an explicit if/else. Or if I really wanted a ternary, I'd rearrange this to:
$type = $self->{1}{_flag} & 2 != $self->{2}{_flag} & 2
? 'B'
: $self->{1}{_flag} & 2
? 'A'
: 'C';

Is there a way to improve this ANTLR 3 Grammar for positive and negative integer and decimal numbers?

Is there a way to express this in a less repeative fashion with the optional positive and negative signs?
What I am trying to accomplish is how to express optionally provide positive + ( default ) and negative - signs on number literals that optionally have exponents and or decimal parts.
NUMBER : ('+'|'-')? DIGIT+ '.' DIGIT* EXPONENT?
| ('+'|'-')? '.'? DIGIT+ EXPONENT?
;
fragment
EXPONENT : ('e' | 'E') ('+' | '-') ? DIGIT+
;
fragment
DIGIT : '0'..'9'
;
I want to be able to recognize NUMBER patterns, and am not so concerned about arithmetic on those numbers at that point, I will later, but I am trying to understand how to recognize any NUMBER literals where numbers look like:
123
+123
-123
0.123
+.123
-.123
123.456
+123.456
-123.456
123.456e789
+123.456e789
-123.456e789
and any other standard formats that I haven't thought to include here.
To answer your question: no, there is no way to improve this AFAIK. You could place ('+' | '-') inside a fragment rule and use that fragment, just like the exponent-fragment, but I wouldn't call it a real improvement.
Note that unary + and - signs generally are not a part of a number-token. Consider the input source "1-2". You don't want that to be tokenized as 2 numbers: NUMBER[1] and NUMBER[-2], but as NUMBER[1], MINUS[-] and NUMBER[2] so that your parser contains the following:
parse
: statement+ EOF
;
statement
: assignment
;
assignment
: IDENTIFIER '=' expression
;
expression
: addition
;
addition
: multiplication (('+' | '-') multiplication)*
;
multiplication
: unary (('*' | '/') unary)*
;
unary
: '-' atom
| '+' atom
| atom
;
atom
: NUMBER
| IDENTIFIER
| '(' expression ')'
;
IDENTIFIER
: ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | DIGIT)*
;
NUMBER
: DIGIT+ '.' DIGIT* EXPONENT?
| '.'? DIGIT+ EXPONENT?
;
fragment
EXPONENT
: ('e' | 'E') ('+' | '-') ? DIGIT+
;
fragment
DIGIT
: '0'..'9'
;
and addition will therefor match the input "1-2".
EDIT
An expression like 111.222 + -456 will be parsed as this:
and +123 + -456 as: