rj-action-library/Runtime/Text/RegexUtility.cs

527 lines
12 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;
using System.Globalization;
using Godot;
namespace Rokojori
{
public class RegexUtility
{
public static Regex MakeSticky( Regex regex )
{
var source = MakeSourceSticky( regex + "" );
return new Regex( source, regex.Options );
}
public static string MakeSourceSticky( string source )
{
if ( ! source.StartsWith( "\\G" ) )
{
source = "\\G(?:" + source + ")";
}
return source;
}
public static string NumberToString( double value )
{
try
{
var specifier = "G";
return value.ToString( specifier, CultureInfo.InvariantCulture );
}
catch( System.Exception e )
{
RJLog.Log(e );
}
return "0";
}
public static double ParseDouble( string source, double alternative = 0 )
{
try
{
double newValue = System.Double.Parse( source, CultureInfo.InvariantCulture );
return newValue;
}
catch ( System.Exception e )
{
if ( e != null )
{
}
return alternative;
}
}
public static float ParseFloat( string source, float alternative = 0 )
{
return ( float ) ParseDouble( source, alternative );
}
public static int ParseInt( string source, int alternative = 0 )
{
var multiply = 1;
var value = 0;
for ( int i = source.Length - 1; i >= 0 ; i-- )
{
var symbol = source[ i ];
if ( i == 0 )
{
if ( symbol == '-' )
{
return - value;
}
if ( symbol == '+' )
{
return value;
}
}
var digitValue = ParseDigit( symbol );
if ( digitValue == -1 )
{
return alternative;
}
value += digitValue * multiply;
multiply *= 10;
}
return value;
}
public static int ParseDigit( char c )
{
switch ( c )
{
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
}
return -1;
}
public static bool Matching( string source, string regex )
{
return new Regex( regex ).Match( source ).Success;
}
public static string Substring( string source, string regex )
{
return new Regex( regex ).Match( source ).Value;
}
public static string EscapeForRegex( string source )
{
var sb = new StringBuilder();
var escapes = "+*?^$\\.[]{}()|/";
for ( int i = 0; i < source.Length; i++ )
{
var character = source[ i ];
if ( escapes.IndexOf( character ) != -1 )
{
sb.Append( "\\" );
}
sb.Append( character );
}
return sb.ToString();
}
public static string LeadingZeros( int value, int minDigits = 2)
{
var stringValue = value + "";
while ( stringValue.Length < minDigits )
{
stringValue = "0" + stringValue;
}
return stringValue;
}
public static string NumberWithThousandsSeperator( int value, string seperator = "." )
{
var isNegative = value < 0;
if ( isNegative ){ value = - value; }
var stringValue = value + "";
var builder = new StringBuilder();
for ( int i = 0; i < stringValue.Length; i++ )
{
var index = ( stringValue.Length - 1 ) - i ;
if ( i % 4 == 3 )
{
builder.Append( seperator );
}
builder.Append( stringValue[ index ] );
}
var seperatorValue = builder.ToString();
return Reverse( seperatorValue );
}
public static string Reverse( string source )
{
char[] characters = source.ToCharArray();
System.Array.Reverse( characters );
return new string( characters );
}
public static Regex EscapedOrRegex( string first, params string[] other )
{
var value = EscapeForRegex( first );
for ( var i = 0; i < other.Length; i++ )
{
value += "|" + EscapeForRegex( other[ i ] );
/*
if ( i == 0 )
{
value = "(" + value;
}
value += ")|(" + EscapeForRegex( other[ i ] );
if ( i == ( other.Length - 1 ) )
{
value += ")";
}
*/
}
//Logs.Log("EscapedOrRegex:", "'" + value + "'");
return new Regex( value );
}
public static Color ParseColor( string source, Color alternative )
{
if ( Matching( source, @"#\d+" ) )
{
return ParseHexColor( source, alternative );
}
else if ( Matching( source, @"^rgb" ) )
{
return ParseRGBColor( source, alternative );
}
else if ( Matching( source, @"^hsl" ) )
{
return ParseHSLColor( source, alternative );
}
return alternative;
}
public static double ParsePercentage( string source )
{
source = Remove( source, @"\s*%" );
return ParseDouble( source.Trim(), 0 ) / 100.0;
}
public static int ParseHexCharacter( char hexCharacter )
{
if ( '0' <= hexCharacter && hexCharacter <= '9' )
{
return (int) (hexCharacter - '0' );
}
if ( 'a' <= hexCharacter && hexCharacter <= 'f' )
{
return (int) (hexCharacter - 'a') + 10;
}
if ( 'A' <= hexCharacter && hexCharacter <= 'F' )
{
return (int) (hexCharacter - 'A') + 10;
}
return 0;
}
public static int ParseHex( string source )
{
var value = 0;
var shift = 0;
for ( var i = source.Length - 1; i < source.Length; i++ )
{
var hexValue = ParseHexCharacter( source[ i ] ) << shift;
shift += 4;
}
return value;
}
public static Color ParseHexColor( string source, Color alternative )
{
source = RegexUtility.Remove( source, @"^#" );
var numbers = new List<float>();
for ( var i = 0; i < 3; i++ )
{
var value = source.Substring( i * 2, 2 );
var numberValue = ParseHex( value ) / 255f;
numbers.Add( numberValue );
}
if ( numbers.Count == 3 )
{
numbers.Add( 1f );
}
return new Color( numbers[ 0 ], numbers[ 1 ], numbers[ 2 ] , numbers[ 3 ] );
}
public static Color ParseRGBColor( string source, Color alternative )
{
source = RegexUtility.Remove( source, @"^rgba?\(" );
source = RegexUtility.Remove( source, @"\)$" );
var splits = Split( source, @"\," );
var numbers = Lists.Map<string,float>( splits,
( string value, int index ) =>
{
if ( value.Contains( "%" ) )
{
return (float) ParsePercentage( value );
}
return ParseFloat( value );
}
);
if ( numbers.Count == 3 )
{
numbers.Add( 1f );
}
return new Color( numbers[ 0 ], numbers[ 1 ], numbers[ 2 ] , numbers[ 3 ] );
}
public static HSLColor ParseHSLColor( string source, HSLColor alternative )
{
source = RegexUtility.Remove( source, @"^hsl\(" );
source = RegexUtility.Remove( source, @"\)$" );
var splits = Split( source, @"\," );
var numbers =Lists.Map<string,float>( splits,
( string value, int index ) =>
{
if ( value.Contains( "%" ) )
{
return (float) ParsePercentage( value );
}
return ParseFloat( value );
}
);
if ( numbers.Count < 3 )
{
RJLog.Log("Not enough numbers parsed: ", source, ">>", numbers.Count, Lists.Join( numbers, "," ) );
}
if ( numbers.Count == 3 )
{
numbers.Add( 1f );
}
return new HSLColor( numbers[ 0 ], numbers[ 1 ], numbers[ 2 ] , numbers[ 3 ] );
}
public static List<string> Split( string source, Regex regex )
{
var strings = regex.Split( source );
var list = new List<string>();
list.AddRange( strings );
return list;
}
public static List<string> Split( string source, string regex )
{
return Split( source, new Regex( regex ) );
}
public static List<string> SplitLines( string source )
{
var array = Regex.Split( source, "\r\n|\r|\n" );
var list = new List<string>();
list.AddRange( array );
return list;
}
public static string Remove( string source, string regex )
{
return Replace( source, regex, "" );
}
public static string Replace( string source, Regex regex, string replacement )
{
return regex.Replace( source, replacement );
}
public static string Remove( string source, Regex regex )
{
return Replace( source, regex, "" );
}
public static string Replace( string source, string regex, string replacement )
{
return new Regex( regex ).Replace( source, replacement );
}
public static string ReplaceMultiple( string source, Dictionary<string,string> replacements )
{
var replaced = source;
foreach ( var vk in replacements )
{
replaced = replaced.Replace( vk.Key, vk.Value );
}
return replaced;
}
public static string ParentPathOrLastFragment( string path )
{
var splits = SplitPaths( path );
return splits[ splits.Count - 1 ];
}
public static List<string> SplitPaths( string path )
{
var splittedPaths = new List<string>();
var normalizedPath = NormalizePath( path );
var splits = Split( normalizedPath, new Regex( @"\/" ) );
return splits;
}
public static string JoinPaths( List<string> paths, int startIndex = 0, int length = -1 )
{
var normalizedPaths = new List<string>();
// normalizedPaths.AddRange( paths );
var endIndex = startIndex + length;
var end = ( length < 0 || ( length + startIndex ) >= paths.Count ) ? paths.Count : endIndex;
for ( var i = startIndex; i < end; i++ )
{
normalizedPaths.Add( _NormalizePath( paths[ i ] ) );
}
return Lists.Join( normalizedPaths, "/" );
}
public static string Join( string pathA, string pathB, params string[] paths )
{
var normalizedPaths = new List<string>();
normalizedPaths.Add( pathA );
normalizedPaths.Add( pathB );
normalizedPaths.AddRange( paths );
for ( var i = 0; i < normalizedPaths.Count; i++ )
{
normalizedPaths[ i ] = _NormalizePath( normalizedPaths[ i ] );
}
return Lists.Join( normalizedPaths, "/" );
}
private static string _EnsureForwardSlashes( string path )
{
if ( path.IndexOf( "\\" ) == -1 )
{
return path;
}
var correctedPath = "";
for ( int i = 0; i < path.Length; i++ )
{
if ( path[ i ] == '\\' )
{
correctedPath += "/";
}
else
{
correctedPath += path[ i ];
}
}
return correctedPath;
}
public static string NormalizePath( string path )
{
return _NormalizePath( path );
}
public static string WindowsPath( string path )
{
path = _NormalizePath( path );
var slashes = @"\/";
path = Regex.Replace( path, slashes, "\\" );
return path;
}
private static string _NormalizePath( string path )
{
path = _EnsureForwardSlashes( path );
var startSlashes = @"^\/+";
var endSlashes = @"\/+$";
var multiples = @"\/\/+";
path = Regex.Replace( path, startSlashes, "" );
path = Regex.Replace( path, endSlashes, "" );
path = Regex.Replace( path, multiples, "/" );
return path;
}
}
}