RegEx for credit-card-numbers with spaces/dash delimiters

I’ve used regular expressions from http://www.richardsramblings.com/regex/credit-card-numbers/ that supports delimiters spaces/dashes, e.g. “3714-496353-98431” or “3714 496353 98431”. (by the way I’ve added Diner’s Club pattern  ((?:30[0-59]|(?:(?:36|38|39)[0-9]))[0-9]{11}) even they are obsolete now)
Unfortunately they use backreferences \1 in individual credit card matches, which doesn’t work if I use alternatives (Visa)|(Master)|(Amex).
I replaced numbered capturing groups with named capturing groups http://www.regular-expressions.info/named.html .
Javascript and .Net format for named groups are different. I’ve done initially using ?P syntax
(?<!\d)(?:(4\d{3}((?P[\ \-]?)(?:\d{4}(?P=DelimVI)){2}\d(?:\d{3})?)|(5([1-5]\d{2})(?P[\ \-]?)\d{4}(?P=DelimMC)\d{4}(?P=DelimMC)\d{4})|(3[47]\d\d(?P[\ \-]?)\d{6}(?P=DelimAX))\d{5}))(?!\d)
and then had to translate to .Net syntax
(?<!\d)(?:(4\d{3}(?’DelimVI'[\ \-]?)(?:\d{4}\k’DelimVI’){2}\d(?:\d{3})?)|(5([1-5]\d{2})(?’DelimMC'[\ \-]?)\d{4}\k’DelimMC’\d{4}\k’DelimMC’\d{4})|(3[47]\d\d(?’DelimAX’)[\ \-]?)\d{6}\k’DelimAX’\d{5}))(?!\d)
I’ve tested Javascript syntax in RegEx101 (see https://regex101.com/r/dX5zJ4/3), but for .Net I had to use http://regexstorm.net/tester and they are not comparable-RegEx101 is significantly user friendlier.

#credit-cards, #regex, #regular-expressions

Advertisements

Use negative look-arounds regex to ensure pattern not surrounded by undesired characters.

I need to extract from text possible credit card numbers. I have regex for different types of credit cards from http://www.richardsramblings.com/regex/credit-card-numbers/. But if the match preceded or followed by any digit, it is not considered as a valid credit card number, but just as unrelated number.
I’ve tried to add non-capturing group (?:\D|) before and after expected card regex,e.g
(?:\D|^)(?:(?:(?:(4[0-9]{12}(?:[0-9]{3})?))|(3[47][0-9]{13}))(?:\D|$))
It mostly works OK, but if 2 credit cards are next to each other, separated by single character:
 4740515144050,378282246310005
the first card matched, but the second is not found.
Negative lookahead is indispensable if you want to match something not followed by something else.
So I was able to search what I need using negative look-arounds: negative lookbehind (?<!\d) before the expression and negative lookahead (?!\d) after the expression
(?<!\d)(?:(?:(?:(4[0-9]{12}(?:[0-9]{3})?))|(3[47][0-9]{13})|(?:5[1-5][0-9]{14}))(?!\d))
See my example of regex in https://regex101.com/r/iY2aR6/8

 

I want to clarify that the purpose of non-capturing groups is different to look-arounds .
In regex, normal parentheses not only group parts of a pattern, they also capture the sub-match to a capture group.  At other times, you do not need the overhead.
If you need parentheses to work in natural way to only group parts of a pattern, you need to specify non-capturing group by putting ?: after opening parenthesis

#lookahead, #lookbehind, #non-capturing-group

Is it possible to determine Visual Studio edition during c# compile time

To use MS Fakes shims, I had to conditionally exclude related tests  to allow easily bypass them on Community and Professional Editions of the Visual Studio.
#if !FAKES_NOT_SUPPORTED
[ TestMethod()]
Fakes related code
#endif
I tried to find does edition automatically pre-defined by compiler, but it’s not included in Conditional Compilation Constants

Furthermore,  these constants seems defined in VB only, and not in c# and not updated since VS2008.

The reasons are discussed in “Pre-defined Constants, preprocessor directives, etc… “

The “C# Language Designers” decided to not include constants in the fashion in which C/C++ allows them.  To allow some, or even one, would open a Pandora’s Box of voices suggesting new constants to be added.

But I disagree,  because if the limitation coming from VS , it should provide a way to  determine it in pre-condition.
The related article shows how to check installed Visual Studio on run-time
Unfortunately I didn’t find, is it possible to determine Visual Studio edition  during c# compile time?

#compile-time, #constants, #visual-studio

Prevent closing PowerShell scripts running from File Explore

For PowerShell scripts to be run from File Explorer it’s important that they not closed automatically.
I am adding to those scripts
if ($host.name -eq ‘ConsoleHost’)
{
  Read-Host -Prompt “Press_Enter_to_continue”
}
Alternately, we can modify the “(Default)” values for our Command keys to include the “-NoExit” parameter.
First I decided,that it is a good idea,and added

 

Set-ItemProperty  HKCR:\Microsoft.PowerShellScript.1\Shell\Command ‘(Default)’  ‘”C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe” “-NoExit” “-ExecutionPolicy” “RemoteSigned” “-file” “%1″‘

 

But then I realized, that  if PowerShell script should be shared with other users, it’s better to explicitly implement pause in a script rather then rely on registry setting on other machines.

Write-Host And Write-Debug differently interpret double quotes

I have a string, that I wanted to output. I’ve tried Write-Debug and it caused error due to unescaped double quote.However when I used Write-Host, the same string was output successfully with unescaped double quotes just ignored.

$DebugPreference = “Continue”
Write-Host ” /cttDir=” \Base Config”  ”

Write-Debug ” /cttDir=” \Base Config”  ”

Output:
 /cttDir= \Base Config 

Write-Debug : A positional parameter cannot be found that accepts argument ‘\Base’.

At C:\Users\Temp\a15f78a2-cf2b-49b7-b6e7-bb7aef345639.ps1:3 char:1

+ Write-Debug ” /cttDir=”\Base Config”  ”

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidArgument: (:) [Write-Debug], ParameterBindingException

    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.WriteDebugCommand.
For this purpose Write-Host is more convenient, but the right way to fix is to escape double quotes inside the string.

#powershell, #write-debug, #write-host

Microsoft Fakes Test Using TimeZoneInfo shim.

I wanted to create a unit test using MS Fakes Framework to replace TimeZoneInfo with Shim (example how to do it see e.g. “Using shims to isolate your application from other assemblies for unit testing”  )

Initially I found that ShimTimeZoneInfo wasn’t generated. After some search I found that Microsoft made some decisions for us/:

What we’ve seen is that user simply want to shim a few type(s) in it.  Due to this, we selectively shimming the commonly used type in the system/mscorlib.

But they didn’t mention it in the documentation.

The actual classes that are generated can be see in FakesAssemblies .fakesconfig files\ (e.g. mscorlib.4.0.0.0.Fakes.fakesconfig)

Fortunately, you can request the compiler to generate shims for specific objects(http://stackoverflow.com/questions/16154182/shims-are-not-generated-for-net-methods)

There are more details in “Code generation, compilation, and naming conventions in Microsoft Fakes”. However note that examples have missing version in lines like

<Assembly Name=”System” Version=”4.0.0.0″/>

So do not copy them literally.

You can specify only what you need and disable StubGeneration

mscorlib.fakes:

<Fakes xmlns=”http://schemas.microsoft.com/fakes/2011/“>

<Assembly Name=”mscorlib” Version=”4.0.0.0″ />

<StubGeneration Disable=”true”/>

<ShimGeneration>

<Add FullName=”System.Environment”/>

<Add FullName=”System.TimeZoneInfo”/>

<Add FullName=”System.DateTime”/>

</ShimGeneration>

</Fakes>

My code also used DateTime.ToUniversalTime, but even ShimDateTime class was generated, particular ShimDateTime.ToUniversalTime was not generated. I haven’t found a way to generate it.

After decompiling I found that the method is a wrapper of TimeZoneInfo method

[__DynamicallyInvokable]

public DateTime ToUniversalTime()

{

return TimeZoneInfo.ConvertTimeToUtc(this , TimeZoneInfoOptions.NoThrowOnInvalidTime);

}

but the overload DateTime ConvertTimeToUtc( DateTime dateTime, TimeZoneInfoOptions flags) is internal (Shim has methods for public overloads static public DateTime ConvertTimeToUtc(DateTime dateTime) and static public DateTime ConvertTimeToUtc( DateTime dateTime, TimeZoneInfo sourceTimeZone))

I’ve had to change in my code

DateTime utcTime = inputDateTime.ToUniversalTime();

to

DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(inputDateTime);

to make it testable.

Because Fakes are available in VS Premium/Ultimate editions 2012/2013 and Enterprise 2015(i.e not available in Community and Professional Editions) I wrapped the test methods in #if !FAKES_NOT_SUPPORTED conditions, to allow easily exclude them on Community and Professional Editions

#if !FAKES_NOT_SUPPORTED

[ TestMethod()]

public void ConvertServerTimeToTimeZoneTimeTest()

{

DateTime inputDateTime = DateTime.Now;

string zoneId = “China Standard Time”;

DateTime timeZoneTime;

//Act

using ( ShimsContext.Create()) //Uses Fakes assembly because TimeZoneInfo may change depending on daylight saving,

{ // hook delegate to the shim method to redirect

TimeZoneInfo.ConvertTimeFromUtc(utcTime, timeInfo);

ShimTimeZoneInfo.ConvertTimeToUtcDateTime = (inputTime) => inputTime.AddHours(-10);

ShimTimeZoneInfo.ConvertTimeFromUtcDateTimeTimeZoneInfo = (utcTime, timeInfo) => utcTime.AddHours(+8);

//Act

timeZoneTime = DateTimeHelper.ConvertServerTimeToTimeZoneTime(inputDateTime, zoneId, true);

}

//Assert

var diff = timeZoneTime – inputDateTime;

diff.Hours.Should().Be(-2);

}

}

#endif //!FAKES_NOT_SUPPORTED

To run Fakes, it’s required to replace legacy MStest.exe test  runner with new VSTest.Console.exe- see my post Replace MSTest to VSTest to support Fakes.

It also was required to do changes in build script, upgrade to latest versions OpenCover and NSubstitute.

#fakes-shims-test

Visual Studio 15 build Task could not find “sgen.exe”

On new Windows 10 machine with Visual Studio 2015 installed when I tried to build my solution from batch file, I’ve got an error

c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets(2769,5): error MSB3086: Task could not find “s
gen.exe” using the SdkToolsPath “C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\” or the regis
try key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools-x86”. Make sure the Sdk
ToolsPath is set and the tool exists in the correct processor specific location under the SdkToolsPath and that the Mic
rosoft Windows SDK is installed

http://stackoverflow.com/questions/2731365/running-msbuild-fails-to-read-sdktoolspath
suggested to Install Microsoft Windows SDK for Windows 7 and .NET Framework AKA v7.1.

But I’ve got error: Windows SDK Setup
Some Windows SDK components require the RTM .NET Framework 4. Setup detected a pre-release version of the .NET Framework 4. If you continue with Setup, these components will not be installed. If you want to install these components, click Cancel, then install the .NET Framework 4 from http://go.microsoft.com/fwlink/?LinkID=187668 and then rerun Setup.
The message is misleading, because I have .net framework 4.6, but I Tried to install the .NET Framework 4 from https://www.microsoft.com/en-us/download/details.aspx?id=17851
I’ve got expected message:
Same or higher version of .NET Framework 4 has already been installed on this computer

I’ve tried different suggestions trying to change path and properties in Microsoft.Common.targets, but finally gave up and

Copy sgen.exe, al.exe and al.exe.config from C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools\
to C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\

as suggested at http://stackoverflow.com/questions/4923131/task-could-not-find-al-exe-using-the-sdktoolspath

#build, #visual-studio