Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
scarb 2.11.3
starknet-foundry 0.39.0
scarb 2.9.2
starknet-foundry 0.36.0
local scarb 2.9.2
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
target
.snfoundry_cache/
snfoundry_trace/
coverage/
profile/
29 changes: 29 additions & 0 deletions examples/cairo/scripts/utility_examples/regex_utils/Scarb.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Code generated by scarb DO NOT EDIT.
version = 1

[[package]]
name = "regex"
version = "0.1.0"

[[package]]
name = "regex_utils"
version = "0.1.0"
dependencies = [
"regex",
"snforge_std",
]

[[package]]
name = "snforge_scarb_plugin"
version = "0.36.1"
source = "registry+https://scarbs.xyz/"
checksum = "sha256:c25111b805d5faa9ecca63ef3a040cf20a5340b61be695f5e587d35cb7564eed"

[[package]]
name = "snforge_std"
version = "0.36.1"
source = "registry+https://scarbs.xyz/"
checksum = "sha256:9d7cf4808ba32136c559522b4b64d4d72495169e5f3efa56aea68a77ec02db55"
dependencies = [
"snforge_scarb_plugin",
]
46 changes: 46 additions & 0 deletions examples/cairo/scripts/utility_examples/regex_utils/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[package]
name = "regex_utils"
version = "0.1.0"
edition = "2024_07"

# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html

[dependencies]
starknet = "2.9.2"
regex = { path = "../../regex" }

[dev-dependencies]
snforge_std = "0.36.0"
assert_macros = "2.9.2"

[[target.starknet-contract]]
sierra = true

[scripts]
test = "snforge test"

[tool.scarb]
allow-prebuilt-plugins = ["snforge_std"]

# Visit https://foundry-rs.github.io/starknet-foundry/appendix/scarb-toml.html for more information

# [tool.snforge] # Define `snforge` tool section
# exit_first = true # Stop tests execution immediately upon the first failure
# fuzzer_runs = 1234 # Number of runs of the random fuzzer
# fuzzer_seed = 1111 # Seed for the random fuzzer

# [[tool.snforge.fork]] # Used for fork testing
# name = "SOME_NAME" # Fork name
# url = "http://your.rpc.url" # Url of the RPC provider
# block_id.tag = "latest" # Block to fork from (block tag)

# [profile.dev.cairo] # Configure Cairo compiler
# unstable-add-statements-code-locations-debug-info = true # Should be used if you want to use coverage
# unstable-add-statements-functions-debug-info = true # Should be used if you want to use coverage/profiler
# inlining-strategy = "avoid" # Should be used if you want to use coverage

# [features] # Used for conditional compilation
# enable_for_tests = [] # Feature name and list of other features that should be enabled with it
casm = true

[lib]
11 changes: 11 additions & 0 deletions examples/cairo/scripts/utility_examples/regex_utils/snfoundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Visit https://foundry-rs.github.io/starknet-foundry/appendix/snfoundry-toml.html
# and https://foundry-rs.github.io/starknet-foundry/projects/configuration.html for more information

# [sncast.default] # Define a profile name
# url = "https://free-rpc.nethermind.io/sepolia-juno/v0_7" # Url of the RPC provider
# accounts-file = "../account-file" # Path to the file with the account data
# account = "mainuser" # Account from `accounts_file` or default account file that will be used for the transactions
# keystore = "~/keystore" # Path to the keystore file
# wait-params = { timeout = 300, retry-interval = 10 } # Wait for submitted transaction parameters
# block-explorer = "StarkScan" # Block explorer service used to display links to transaction details
# show-explorer-links = true # Print links pointing to pages with transaction details in the chosen block explorer
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
mod main;

#[cfg(test)]
mod tests {
mod test_main;
}
162 changes: 162 additions & 0 deletions examples/cairo/scripts/utility_examples/regex_utils/src/main.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
use core::byte_array::ByteArray;
use regex::regex::{Regex, RegexTrait};

fn main() {
// Example 1: Creating a new regex and checking if text matches a pattern
println!("== Example 1: new & matches ==");
let email_pattern: ByteArray = "[a-z0-9]+@[a-z]+.[a-z]+";
let mut regex = RegexTrait::new(email_pattern);

let valid_email: ByteArray = "[email protected]";
let invalid_email: ByteArray = "invalid-email";

println!("Valid email: {}", valid_email);
println!("Matches pattern? {}", regex.matches(valid_email.clone()));

println!("Invalid email: {}", invalid_email);
println!("Matches pattern? {}", regex.matches(invalid_email.clone()));

// Example 2: Finding the first occurrence of a pattern
println!("== Example 2: find ==");
let text: ByteArray = "Contact us at [email protected] or [email protected]";
let mut email_regex: Regex = RegexTrait::new("[a-z]+@[a-z]+.[a-z]+");

match email_regex.find(text.clone()) {
Option::Some((
start, end,
)) => {
let mut email = "";
let mut i = start;
while i < end {
email.append_byte(text.at(i).unwrap());
i += 1;
};
println!("Found email: {}", email);
println!("Position: {} to {}", start, end);
},
Option::None => { println!("No email found in text"); },
}

// Example 3: Finding all occurrences of a pattern
println!("== Example 3: find_all ==");
let log_text: ByteArray =
"2024-01-15 ERROR Database connection failed//2024-01-15 ERROR Authentication error//2024-01-15 INFO Retry successful";
let mut error_regex: Regex = RegexTrait::new("ERROR.*");
let matches = error_regex.find_all(log_text.clone());

println!("Found {} error messages:", matches.len());
let mut i = 0;
while i < matches.len() {
let (start, end) = *matches.at(i);
let mut error_msg = "";
let mut j = start;
while j < end {
error_msg.append_byte(log_text.at(j).unwrap());
j += 1;
};
println!(" {}: {}", i + 1, error_msg);
i += 1;
};

// Example 4: Replacing patterns in text
println!("== Example 4: replace ==");
let sensitive_text: ByteArray =
"My credit card is 1234-5678-9012-3456 and my SSN is 123-45-6789";

// Replace credit card numbers
let mut cc_regex: Regex = RegexTrait::new("[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}");
let masked_cc = cc_regex.replace(sensitive_text.clone(), "XXXX-XXXX-XXXX-XXXX");
println!("After masking credit card:");
println!("{}", masked_cc);

// Also replace SSN
let mut ssn_regex: Regex = RegexTrait::new("[0-9]{3}-[0-9]{2}-[0-9]{4}");
let fully_masked = ssn_regex.replace(masked_cc, "XXX-XX-XXXX");
println!("After masking SSN:");
println!("{}", fully_masked);

// Example 5: Matching character classes
println!("== Example 5: Character Classes ==");
let mut digit_regex: Regex = RegexTrait::new("[0-9]+");
let text_with_numbers: ByteArray = "abc123def456";

let matches = digit_regex.find_all(text_with_numbers.clone());
println!("Found {} number sequences:", matches.len());

let mut i = 0;
while i < matches.len() {
let (start, end) = *matches.at(i);
let mut number = "";
let mut j = start;
while j < end {
number.append_byte(text_with_numbers.at(j).unwrap());
j += 1;
};
println!(" {}: {}", i + 1, number);
i += 1;
};

// Example 6: Wildcards
println!("== Example 6: Wildcards ==");
let mut wildcard_regex: Regex = RegexTrait::new("c.t");
let words: ByteArray = "cat cut cot cit";

let matches = wildcard_regex.find_all(words.clone());
println!("Words matching 'c.t' pattern:");

let mut i = 0;
while i < matches.len() {
let (start, end) = *matches.at(i);
let mut word = "";
let mut j = start;
while j < end {
word.append_byte(words.at(j).unwrap());
j += 1;
};
println!(" {}", word);
i += 1;
};

// Example 7: Quantifiers
println!("== Example 7: Quantifiers ==");
let text: ByteArray = "color colour flavor flavour";

// Zero or one occurrence (American/British spelling)
let mut color_regex: Regex = RegexTrait::new("colou?r");
let matches = color_regex.find_all(text.clone());

println!("Words matching 'colou?r' (zero or one 'u'):");
let mut i = 0;
while i < matches.len() {
let (start, end) = *matches.at(i);
let mut word = "";
let mut j = start;
while j < end {
word.append_byte(text.at(j).unwrap());
j += 1;
};
println!(" {}", word);
i += 1;
};

// One or more occurrences
let mut letters_regex: Regex = RegexTrait::new("a+");
let repeated_text: ByteArray = "a aa aaa aaaa";
let matches = letters_regex.find_all(repeated_text.clone());

println!("Sequences matching 'a+' (one or more 'a'):");
let mut i = 0;
while i < matches.len() {
let (start, end) = *matches.at(i);
let mut sequence = "";
let mut j = start;
while j < end {
sequence.append_byte(repeated_text.at(j).unwrap());
j += 1;
};
println!(" {}: {} a's", i + 1, end - start);
i += 1;
};

println!("== End of Examples ==");
}
Loading