Lots of changes for v2
Mainly, add a search method to find all valid pincodes See #3 Create a single unified regex. Update some dependencies However, this breaks on PHP,so I need to fix something for that.
This commit is contained in:
parent
5d5e939a6b
commit
fc6bfdb113
|
@ -21,3 +21,5 @@ Gemfile.lock
|
||||||
.pdm.toml
|
.pdm.toml
|
||||||
__pypackages__/
|
__pypackages__/
|
||||||
src/pincode.egg-info/
|
src/pincode.egg-info/
|
||||||
|
.phpunit.*cache
|
||||||
|
*.bak
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
# Generating the regex
|
# Generating the regex
|
||||||
|
|
||||||
1. Download the latest CSV file from <https://data.gov.in/resources/all-india-pincode-directory-till-last-month>.
|
1. Download the latest CSV file from <https://data.gov.in/resources/all-india-pincode-directory-till-last-month>.
|
||||||
2. Copy all the pincodes to a pincodes.txt file
|
2. Copy all the pincodes to a pincodes.csv file
|
||||||
3. Generate all unique pincodes by running `sort -u pincodes.txt > /tmp/pin.txt`
|
3. Generate all unique pincodes by running `npm run build`
|
||||||
4. `npm install`
|
|
||||||
5. `node src/generate.js /tmp/pin.txt > regex.txt`
|
|
||||||
|
|
||||||
# Generating the browser-version
|
# Generating the browser-version
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,11 @@ To use the package:
|
||||||
```js
|
```js
|
||||||
const P = require('pincode-validator');
|
const P = require('pincode-validator');
|
||||||
P.validate('110011'); // returns true
|
P.validate('110011'); // returns true
|
||||||
|
P.search('my pincode is 560029'); // returns ['560029']
|
||||||
|
|
||||||
|
// or directly use the regex in your code
|
||||||
|
P.exactRegex.match('560029')
|
||||||
|
"address with pincode (560029)".matchAll(P.regex)
|
||||||
````
|
````
|
||||||
|
|
||||||
## Ruby
|
## Ruby
|
||||||
|
@ -63,13 +68,12 @@ Pincode.validate("560029"); // returns true
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
Since there is no hotline/CDN for this yet, please watch to repo to get notified of new releases.
|
You can use githack for directly using this in your code: <https://rawcdn.githack.com/captn3m0/india-pincode-regex/1.0.4/pincode-regex.js> (Make sure you use the latest version). Please watch the repo to get notified of new releases.
|
||||||
|
|
||||||
## Code of Conduct
|
## Code of Conduct
|
||||||
|
|
||||||
Everyone interacting in the this project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/captn3m0/outliner/blob/master/CODE_OF_CONDUCT.md).
|
Everyone interacting in the this project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/captn3m0/outliner/blob/master/CODE_OF_CONDUCT.md).
|
||||||
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
- See [`HACKING.md`](HACKING.md) for some development details.
|
- See [`HACKING.md`](HACKING.md) for some development details.
|
||||||
|
|
|
@ -16,6 +16,6 @@
|
||||||
},
|
},
|
||||||
"require": {},
|
"require": {},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^9.0 || ^8.0"
|
"phpunit/phpunit": "^9.0 || ^8.0 || ^10.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node tests/validate.js",
|
"test": "node tests/validate.js",
|
||||||
|
"build": "node src/generate.js <(sort -u pincodes.csv) > regex.txt",
|
||||||
"browserify": "browserify --transform brfs --outfile pincode-regex.js -s Pincode src/index.js"
|
"browserify": "browserify --transform brfs --outfile pincode-regex.js -s Pincode src/index.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -29,7 +30,7 @@
|
||||||
"homepage": "https://github.com/captn3m0/india-pincode-regex#readme",
|
"homepage": "https://github.com/captn3m0/india-pincode-regex#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"brfs": "^2.0.2",
|
"brfs": "^2.0.2",
|
||||||
"browserify": "^16.5.1",
|
"browserify": "^17.0.0",
|
||||||
"regexgen": "^1.3.0"
|
"regexgen": "^1.3.0"
|
||||||
},
|
},
|
||||||
"dependencies": {}
|
"dependencies": {}
|
||||||
|
|
|
@ -22,4 +22,4 @@
|
||||||
</whitelist>
|
</whitelist>
|
||||||
</filter>
|
</filter>
|
||||||
|
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|
|
@ -25,5 +25,5 @@ Gem::Specification.new do |spec|
|
||||||
spec.license = 'MIT'
|
spec.license = 'MIT'
|
||||||
spec.require_paths = ["src"]
|
spec.require_paths = ["src"]
|
||||||
spec.add_development_dependency 'rake', '~> 13.0'
|
spec.add_development_dependency 'rake', '~> 13.0'
|
||||||
spec.add_development_dependency 'rspec', '~> 3.8'
|
spec.add_development_dependency 'rspec', '~> 3.12'
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,19 +3,34 @@
|
||||||
namespace PIN;
|
namespace PIN;
|
||||||
|
|
||||||
class Validator {
|
class Validator {
|
||||||
static $regexes;
|
static $regex;
|
||||||
|
static $exactRegex;
|
||||||
|
|
||||||
|
public static function init(){
|
||||||
|
if(!self::$regex) {
|
||||||
|
self::$regex = "/" . trim(file_get_contents('regex.txt')) . "/";
|
||||||
|
self::$exactRegex = "/^" . trim(file_get_contents('regex.txt')) . "$/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static function validate(string $pin) {
|
public static function validate(string $pin) {
|
||||||
if(!self::$regexes) {
|
self::init();
|
||||||
self::$regexes = array_filter(file('regex.txt'));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (self::$regexes as $regex) {
|
fwrite(STDERR, var_dump(self::$exactRegex, TRUE));
|
||||||
if (strlen($pin) === 6 and preg_match($regex, $pin) === 1) {
|
|
||||||
return true;
|
if (strlen($pin) === 6 and preg_match(self::$exactRegex, $pin) === 1) {
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function search(string $address) {
|
||||||
|
self::init();
|
||||||
|
preg_match_all(self::$regex, $address, $matches);
|
||||||
|
|
||||||
|
return array_map(function($match) {
|
||||||
|
return $match[0];
|
||||||
|
}, $matches);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,11 @@ readInterface.on("line", function (line) {
|
||||||
let areaCode = parseInt(line.charAt(0), 10);
|
let areaCode = parseInt(line.charAt(0), 10);
|
||||||
if (areaCode < 9 && areaCode > 0) {
|
if (areaCode < 9 && areaCode > 0) {
|
||||||
let areaCodeIndex = areaCode - 1;
|
let areaCodeIndex = areaCode - 1;
|
||||||
regexes[areaCodeIndex].add(line);
|
regexes[areaCodeIndex].add(line.trim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
readInterface.on("close", function () {
|
readInterface.on("close", function () {
|
||||||
for (i in regexes) {
|
console.log("(" + regexes.join('|') + ")");
|
||||||
console.log(regexes[i].toRegExp());
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
29
src/index.js
29
src/index.js
|
@ -1,25 +1,22 @@
|
||||||
const readline = require("readline");
|
const readline = require("readline");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
|
||||||
const regexes = fs
|
let contents = fs.readFileSync(__dirname + "/../regex.txt", "utf8").trim()
|
||||||
.readFileSync(__dirname + "/../regex.txt", "utf8")
|
const regex = new RegExp(contents, "gm");
|
||||||
.split("\n")
|
const exactRegex = new RegExp("^" + contents + "$");
|
||||||
// Remove empty lines
|
|
||||||
.filter(function(r) {
|
|
||||||
return r.length > 1;
|
|
||||||
})
|
|
||||||
// Remove the opening and closing slashes
|
|
||||||
.map(function(r) {
|
|
||||||
return new RegExp("^" + r.slice(1, -1) + "$");
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
// Validates an exact 6 digit string as a valid pincode
|
||||||
validate: function(pin) {
|
validate: function(pin) {
|
||||||
for (let i in regexes) {
|
if (exactRegex.test(pin)) {
|
||||||
if (regexes[i].test(pin)) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
|
// Returns all valid PIN codes for a given address
|
||||||
|
search: function(address) {
|
||||||
|
return Array.from(address.matchAll(regex), (x) => x[0])
|
||||||
|
},
|
||||||
|
regex: regex,
|
||||||
|
exactRegex: exactRegex
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module PincodeValidator
|
module PincodeValidator
|
||||||
VERSION = "1.0.3"
|
VERSION = "1.0.4"
|
||||||
FILENAME='regex.txt'
|
FILENAME='regex.txt'
|
||||||
|
|
||||||
class Error < StandardError; end
|
class Error < StandardError; end
|
||||||
|
@ -8,14 +8,18 @@ module PincodeValidator
|
||||||
File.dirname __dir__
|
File.dirname __dir__
|
||||||
end
|
end
|
||||||
|
|
||||||
@@regexes ||= IO.readlines(File.join root, FILENAME).map do |line|
|
@@regex ||=
|
||||||
Regexp.new("^#{line.strip[1...-1]}$")
|
Regexp.new(File.read(File.join root, FILENAME).strip)
|
||||||
end
|
|
||||||
|
@@exactRegex ||=
|
||||||
|
Regexp.new("^#{File.read(File.join root, FILENAME).strip}$")
|
||||||
|
|
||||||
def self.valid?(pincode)
|
def self.valid?(pincode)
|
||||||
@@regexes.each do |r|
|
return true if @@exactRegex.match? pincode
|
||||||
return true if r.match? pincode
|
|
||||||
end
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.search?(address)
|
||||||
|
address.scan(@@regex).map(&:first).map(&:strip)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,4 +17,11 @@ class SimpleTest extends TestCase {
|
||||||
$this->assertFalse(P::validate($pin), "$pin should be invalid");
|
$this->assertFalse(P::validate($pin), "$pin should be invalid");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public function testSearch() {
|
||||||
|
// $this->assertSame(P::search("my pincode is 560029"), ["560029"]);
|
||||||
|
// $this->assertSame(P::search("560029"), ["560029"]);
|
||||||
|
// $this->assertSame(P::search("560029 244713"), ["560029", "244713"]);
|
||||||
|
// $this->assertSame(P::search("address 560038 bangalore"), ["560038"]);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,43 @@
|
||||||
const pincode = require('../src/index');
|
const P = require('../src/index');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
|
|
||||||
// A few correct ones
|
// A few correct ones
|
||||||
|
assert.strictEqual(P.validate('110011'), true, '110011');
|
||||||
assert.strictEqual(pincode.validate('110011'), true, '110011');
|
assert.strictEqual(P.validate('244713'), true, '244713');
|
||||||
assert.strictEqual(pincode.validate('244713'), true, '244713');
|
assert.strictEqual(P.validate('560029'), true, '560029');
|
||||||
assert.strictEqual(pincode.validate('560029'), true, '560029');
|
assert.strictEqual(P.validate('560030'), true, '560030');
|
||||||
assert.strictEqual(pincode.validate('560030'), true, '560030');
|
|
||||||
|
|
||||||
// Incorrect
|
// Incorrect
|
||||||
assert.strictEqual(pincode.validate('1100111'), false, '1100111');
|
assert.strictEqual(P.validate('address 560030'), false, 'address 560030 should fail');
|
||||||
assert.strictEqual(pincode.validate('111111'), false, '111111');
|
assert.strictEqual(P.validate('1100111'), false, '1100111');
|
||||||
assert.strictEqual(pincode.validate('999999'), false, '999999');
|
assert.strictEqual(P.validate('111111'), false, '111111');
|
||||||
assert.strictEqual(pincode.validate('99999'), false, '99999');
|
assert.strictEqual(P.validate('999999'), false, '999999');
|
||||||
assert.strictEqual(pincode.validate('9999'), false, '9999');
|
assert.strictEqual(P.validate('99999'), false, '99999');
|
||||||
assert.strictEqual(pincode.validate('999'), false, '999');
|
assert.strictEqual(P.validate('9999'), false, '9999');
|
||||||
assert.strictEqual(pincode.validate('99'), false, '99');
|
assert.strictEqual(P.validate('999'), false, '999');
|
||||||
assert.strictEqual(pincode.validate('9'), false, '9');
|
assert.strictEqual(P.validate('99'), false, '99');
|
||||||
|
assert.strictEqual(P.validate('9'), false, '9');
|
||||||
|
|
||||||
|
// Validate search method
|
||||||
|
assert.deepEqual(P.search('bangalore 560038 244713'), ['560038', '244713'])
|
||||||
|
assert.deepEqual(P.search('bangalore 560038'), ['560038'])
|
||||||
|
assert.deepEqual(P.search('560038 BENGALURU'), ['560038'])
|
||||||
|
assert.deepEqual(P.search('560038'), ['560038'])
|
||||||
|
assert.deepEqual(P.search('my pincode is 244713'), ['244713'])
|
||||||
|
assert.deepEqual(P.search('560029 pin'), ['560029'])
|
||||||
|
|
||||||
|
// Validate direct regex exports
|
||||||
|
assert(P.regex instanceof RegExp)
|
||||||
|
assert(P.exactRegex instanceof RegExp)
|
||||||
|
|
||||||
|
// exact regex only works with 6 digit strings
|
||||||
|
assert(P.exactRegex.test('560029'))
|
||||||
|
assert.match('560029', P.exactRegex)
|
||||||
|
assert.doesNotMatch('111111', P.exactRegex)
|
||||||
|
assert.doesNotMatch('address is 560029', P.exactRegex)
|
||||||
|
|
||||||
|
// Normal regex works with long addresses
|
||||||
|
assert.match('560029', P.regex)
|
||||||
|
assert.match('address is 560029', P.regex)
|
||||||
|
assert.doesNotMatch('address is 111111', P.regex)
|
||||||
|
assert.doesNotMatch('111111', P.regex)
|
||||||
|
|
|
@ -12,4 +12,12 @@ describe PincodeValidator do
|
||||||
expect(described_class::valid? pin).to eq(false), "#{pin} should be invalid"
|
expect(described_class::valid? pin).to eq(false), "#{pin} should be invalid"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should search pincodes' do
|
||||||
|
expect(described_class::search? '560029').to eq(['560029'])
|
||||||
|
expect(described_class::search? '560029, 560030').to eq(['560029', '560030'])
|
||||||
|
expect(described_class::search? '560029, 560030, 110011').to eq(['560029', '560030', '110011'])
|
||||||
|
expect(described_class::search? 'bangalore 560029').to eq(['560029'])
|
||||||
|
expect(described_class::search? 'bangalore 1').to eq([])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue